Merge "Allow io_* syscalls."
diff --git a/README.md b/README.md
index 61314b6..cd409d9 100644
--- a/README.md
+++ b/README.md
@@ -171,6 +171,10 @@
contents for external/kernel-headers/.
2. Run update_all.py to scrub those headers and import them into bionic.
+Note that if you're actually just trying to expose device-specific headers to
+build your device drivers, you shouldn't modify bionic. Instead use
+`TARGET_DEVICE_KERNEL_HEADERS` and friends described in [config.mk](https://android.googlesource.com/platform/build/+/master/core/config.mk#186).
+
Updating tzdata
---------------
@@ -305,13 +309,23 @@
$ adb shell /data/nativetest/bionic-benchmarks/bionic-benchmarks
$ adb shell /data/nativetest64/bionic-benchmarks/bionic-benchmarks
+When operated without specifying an xml file, the default is to use the xml
+file called full.xml found in the directory `suites/` bound in the same directory
+as the bionic-benchmarks executable.
+
+To use a different xml file, use the `--bionic_xml=FILE.XML` option. By default, this
+option searches for the xml file in the `suites/` directory. If it doesn't exist
+in that directory then the file will be found as relative to the current
+directory. If the option specifies the full path to an xml file such as
+`/data/nativetest/suites/example.xml`, it will be used as is.
+
You can use `--benchmark_filter=getpid` to just run benchmarks with "getpid"
in their name.
### Host benchmarks
-See the "Host tests" section of "Running the tests" above.
-
+See the "Host tests" section of "Running the tests" above. The default for
+host tests is to use the `host.xml` file in the suites directory instead of `full.xml`.
Attaching GDB to the tests
--------------------------
@@ -327,19 +341,54 @@
32-bit ABI bugs
---------------
-This probably belongs in the NDK documentation rather than here, but these
-are the known ABI bugs in the 32-bit ABI:
+### `off_t` is 32-bit.
- * `time_t` is 32-bit. <http://b/5819737>. In the 64-bit ABI, time_t is
- 64-bit.
+On 32-bit Android, `off_t` is a signed 32-bit integer. This limits functions
+that use `off_t` to working on files no larger than 2GiB.
- * `off_t` is 32-bit. There is `off64_t`, and in newer releases there is
- almost-complete support for `_FILE_OFFSET_BITS`. Unfortunately our stdio
- implementation uses 32-bit offsets and -- worse -- function pointers to
- functions that use 32-bit offsets, so there's no good way to implement
- the last few pieces <http://b/24807045>. In the 64-bit ABI, off_t is
- off64_t.
+Android does not require the `_LARGEFILE_SOURCE` macro to be used to make
+`fseeko` and `ftello` available. Instead they're always available from API
+level 24 where they were introduced, and never available before then.
- * `sigset_t` is too small on ARM and x86 (but correct on MIPS), so support
- for real-time signals is broken. <http://b/5828899> In the 64-bit ABI,
- `sigset_t` is the correct size for every architecture.
+Android also does not require the `_LARGEFILE64_SOURCE` macro to be used
+to make `off64_t` and corresponding functions such as `ftruncate64` available.
+Instead, whatever subset of those functions was available at your target API
+level will be visible.
+
+There are a couple of exceptions to note. Firstly, `off64_t` and the single
+function `lseek64` were available right from the beginning in API 3. Secondly,
+Android has always silently inserted `O_LARGEFILE` into any open call, so if
+all you need are functions like `read` that don't take/return `off_t`, large
+files have always worked.
+
+Android support for `_FILE_OFFSET_BITS=64` (which turns `off_t` into `off64_t`
+and replaces each `off_t` function with its `off64_t` counterpart, such as
+`lseek` in the source becoming `lseek64` at runtime) was added late. Even when
+it became available for the platform, it wasn't available from the NDK until
+r15. Before NDK r15, `_FILE_OFFSET_BITS=64` silently did nothing: all code
+compiled with that was actually using a 32-bit `off_t`. With a new enough NDK,
+the situation becomes complicated. If you're targeting an API before 21, almost
+all functions that take an `off_t` become unavailable. You've asked for their
+64-bit equivalents, and none of them (except `lseek`/`lseek64`) exist. As you
+increase your target API level, you'll have more and more of the functions
+available. API 12 adds some of the `<unistd.h>` functions, API 21 adds `mmap`,
+and by API 24 you have everything including `<stdio.h>`. See the
+[linker map](libc/libc.map.txt) for full details.
+
+In the 64-bit ABI, `off_t` is always 64-bit.
+
+### `sigset_t` is too small for real-time signals.
+
+On 32-bit Android, `sigset_t` is too small for ARM and x86 (but correct for
+MIPS). This means that there is no support for real-time signals in 32-bit
+code.
+
+In the 64-bit ABI, `sigset_t` is the correct size for every architecture.
+
+### `time_t` is 32-bit.
+
+On 32-bit Android, `time_t` is 32-bit. The header `<time64.h>` and type
+`time64_t` exist as a workaround, but the kernel interfaces exposed on 32-bit
+Android all use the 32-bit `time_t`.
+
+In the 64-bit ABI, `time_t` is 64-bit.
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index 0edba65..e8745a2 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -25,6 +25,7 @@
"-Wunused",
],
srcs: [
+ "bionic_benchmarks.cpp",
"atomic_benchmark.cpp",
"math_benchmark.cpp",
"property_benchmark.cpp",
@@ -34,8 +35,13 @@
"string_benchmark.cpp",
"time_benchmark.cpp",
"unistd_benchmark.cpp",
+ "stdlib_benchmark.cpp",
],
- static_libs: ["libBionicBenchmarksUtils"],
+ shared_libs: ["libtinyxml2"],
+ static_libs: [
+ "libbase",
+ "libBionicBenchmarksUtils",
+ ],
}
cc_defaults {
@@ -54,6 +60,7 @@
cc_benchmark {
name: "bionic-benchmarks",
defaults: ["bionic-benchmarks-defaults"],
+ data: ["suites/*"],
}
// We don't build a static benchmark executable because it's not usually
@@ -73,6 +80,7 @@
enabled: false,
},
},
+ data: ["suites/*"],
}
cc_library_static {
@@ -87,6 +95,11 @@
defaults: ["bionic-benchmarks-extras-defaults"],
srcs: [
"tests/benchmark_test.cpp",
+ "tests/interface_test.cpp",
],
- static_libs: ["libBionicBenchmarksUtils"],
+ static_libs: [
+ "libbase",
+ "libBionicBenchmarksUtils",
+ ],
+ data: ["suites/*", "test_suites/*"],
}
diff --git a/benchmarks/README.md b/benchmarks/README.md
new file mode 100644
index 0000000..6501839
--- /dev/null
+++ b/benchmarks/README.md
@@ -0,0 +1,66 @@
+Bionic Benchmarks
+=================
+Bionic benchmarks is a command line tool for measuring the runtimes of libc functions. It is built
+on top of [Google benchmarks](https://github.com/google/benchmark) with some additions to organize
+tests into suites.
+
+Instructions for running these can be found in the platform_bionic README.
+
+## Suites
+
+Suites are stored in the `suites/` directory and can be chosen with the command line flag
+'--bionic_xml'. When operated without specifying an xml file, the default is to use the
+file called `full.xml` found in the directory `suites/` bound in the same directory
+as the bionic-benchmarks executable.
+
+To use a different xml file, use the `--bionic_xml=FILE.XML` option. By default, this
+option searches for the xml file in the `suites/` directory. If it doesn't exist
+in that directory then the file will be found as relative to the current
+directory. If the option specifies the full path to an xml file such as
+`/data/nativetest/suites/example.xml`, it will be used as is.
+
+If no xml file is specified through the command-line option, the default is to use `suites/full.xml`.
+However, for the host bionic benchmarks (bionic-benchmarks-glibc), the default
+is to use `suites/host.xml`.
+
+### Format
+
+The format for a benchmark is:
+
+```
+<fn>
+ <name>BM_sample_benchmark</name>
+ <cpu><optional_cpu_to_lock></cpu>
+ <iterations><optional_iterations_to_run></iterations>
+ <args><space separated list of function args|shorthand></args>
+</fn>
+```
+
+xml-specified values for iterations and cpu take precedence over those specified via command line
+(via '--bionic_iterations' and '--bionic_cpu', respectively.)
+
+To make small changes in runs, you can also schedule benchmarks by passing in their name and a
+space-separated list of arguments via the 'bionic_extra' command line flag, e.g.
+'--bionic_extra="BM_string_memcpy AT_COMMON_SIZES"' or '--bionic_extra="BM_string_memcmp 32 8 8"'
+
+Note that benchmarks will run normally if extra arguments are passed in, and it will fail
+with a segfault if too few are passed in.
+
+### Shorthand
+
+For the sake of brevity, multiple runs can be scheduled in one xml element by putting one of the
+following in the args field:
+
+ NUM_PROPS
+ MATH_COMMON
+ AT_ALIGNED_<ONE|TWO>BUF
+ AT_<any power of two between 2 and 16384>_ALIGNED_<ONE|TWO>BUF
+ AT_COMMON_SIZES
+
+Definitions for these can be found in bionic_benchmarks.cpp, and example usages can be found in
+the suites directory.
+
+### Unit Tests
+
+Bionic benchmarks also has its own set of unit tests, which can be run from the binary in
+`/data/nativetest[64]/bionic-benchmarks-tests`
diff --git a/benchmarks/atomic_benchmark.cpp b/benchmarks/atomic_benchmark.cpp
index 66a0120..a584dce 100644
--- a/benchmarks/atomic_benchmark.cpp
+++ b/benchmarks/atomic_benchmark.cpp
@@ -20,10 +20,12 @@
// Expected mappings from C++ atomics to hardware primitives can be found at
// http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html .
-#include <benchmark/benchmark.h>
#include <atomic>
#include <mutex>
+#include <benchmark/benchmark.h>
+#include "util.h"
+
// We time atomic operations separated by a volatile (not atomic!) increment. This ensures
// that the compiler emits memory instructions (e.g. load or store) prior to any fence or the
// like. That in turn ensures that the CPU has outstanding memory operations when the fence
@@ -48,7 +50,7 @@
++counter;
}
}
-BENCHMARK(BM_empty);
+BIONIC_BENCHMARK(BM_empty);
static void BM_load_relaxed(benchmark::State& state) {
unsigned result = 0;
@@ -58,7 +60,7 @@
}
sink = result;
}
-BENCHMARK(BM_load_relaxed);
+BIONIC_BENCHMARK(BM_load_relaxed);
static void BM_load_acquire(benchmark::State& state) {
unsigned result = 0;
@@ -68,7 +70,7 @@
}
sink = result;
}
-BENCHMARK(BM_load_acquire);
+BIONIC_BENCHMARK(BM_load_acquire);
static void BM_store_release(benchmark::State& state) {
int i = counter;
@@ -77,7 +79,7 @@
++counter;
}
}
-BENCHMARK(BM_store_release);
+BIONIC_BENCHMARK(BM_store_release);
static void BM_store_seq_cst(benchmark::State& state) {
int i = counter;
@@ -86,7 +88,7 @@
++counter;
}
}
-BENCHMARK(BM_store_seq_cst);
+BIONIC_BENCHMARK(BM_store_seq_cst);
static void BM_fetch_add_relaxed(benchmark::State& state) {
unsigned result = 0;
@@ -96,7 +98,7 @@
}
sink = result;
}
-BENCHMARK(BM_fetch_add_relaxed);
+BIONIC_BENCHMARK(BM_fetch_add_relaxed);
static void BM_fetch_add_seq_cst(benchmark::State& state) {
unsigned result = 0;
@@ -106,7 +108,7 @@
}
sink = result;
}
-BENCHMARK(BM_fetch_add_seq_cst);
+BIONIC_BENCHMARK(BM_fetch_add_seq_cst);
// The fence benchmarks include a relaxed load to make it much harder to optimize away
// the fence.
@@ -120,7 +122,7 @@
}
sink = result;
}
-BENCHMARK(BM_acquire_fence);
+BIONIC_BENCHMARK(BM_acquire_fence);
static void BM_seq_cst_fence(benchmark::State& state) {
unsigned result = 0;
@@ -131,7 +133,7 @@
}
sink = result;
}
-BENCHMARK(BM_seq_cst_fence);
+BIONIC_BENCHMARK(BM_seq_cst_fence);
// For comparison, also throw in a critical section version:
@@ -145,4 +147,4 @@
}
sink = result;
}
-BENCHMARK(BM_fetch_add_cs);
+BIONIC_BENCHMARK(BM_fetch_add_cs);
diff --git a/benchmarks/bionic_benchmarks.cpp b/benchmarks/bionic_benchmarks.cpp
new file mode 100644
index 0000000..e61233c
--- /dev/null
+++ b/benchmarks/bionic_benchmarks.cpp
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <err.h>
+#include <getopt.h>
+#include <math.h>
+#include <sys/resource.h>
+
+#include <map>
+#include <mutex>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/strings.h>
+#include <benchmark/benchmark.h>
+#include <tinyxml2.h>
+#include "util.h"
+
+#if defined(__ANDROID__)
+static constexpr const char* kDefaultSuite="full.xml";
+#else
+static constexpr const char* kDefaultSuite="host.xml";
+#endif
+
+std::map<std::string, benchmark_func_t> g_str_to_func;
+
+std::mutex g_map_lock;
+
+static struct option g_long_options[] =
+{
+ {"bionic_cpu", required_argument, 0, 'c'},
+ {"bionic_xml", required_argument, 0, 'x'},
+ {"bionic_iterations", required_argument, 0, 'i'},
+ {"bionic_extra", required_argument, 0, 'a'},
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0},
+};
+
+typedef std::vector<std::vector<int>> args_vector_t;
+
+void Usage() {
+ printf("Usage:\n");
+ printf("bionic_benchmarks [--bionic_cpu=<cpu_to_isolate>]\n");
+ printf(" [--bionic_xml=<path_to_xml>]\n");
+ printf(" [--bionic_iterations=<num_iter>]\n");
+ printf(" [--bionic_extra=\"<fn_name> <arg1> <arg 2> ...\"]\n");
+ printf(" [<Google benchmark flags>]\n");
+ printf("Google benchmark flags:\n");
+
+ int fake_argc = 2;
+ char argv0[] = "bionic_benchmarks";
+ char argv1[] = "--help";
+ char* fake_argv[3] {argv0, argv1, NULL};
+ benchmark::Initialize(&fake_argc, fake_argv);
+ exit(1);
+}
+
+// This function removes any bionic benchmarks command line arguments by checking them
+// against g_long_options. It fills new_argv with the filtered args.
+void SanitizeOpts(int argc, char** argv, std::vector<char*>* new_argv) {
+ // TO THOSE ADDING OPTIONS: This currently doesn't support optional arguments.
+ (*new_argv)[0] = argv[0];
+ for (int i = 1; i < argc; ++i) {
+ char* optarg = argv[i];
+ size_t opt_idx = 0;
+
+ // Iterate through g_long_options until either we hit the end or we have a match.
+ for (opt_idx = 0; g_long_options[opt_idx].name &&
+ strncmp(g_long_options[opt_idx].name, optarg + 2,
+ strlen(g_long_options[opt_idx].name)); ++opt_idx) {
+ }
+
+ if (!g_long_options[opt_idx].name) {
+ new_argv->push_back(optarg);
+ } else {
+ if (g_long_options[opt_idx].has_arg == required_argument) {
+ // If the arg was passed in with an =, it spans one char *.
+ // Otherwise, we skip a spot for the argument.
+ if (!strchr(optarg, '=')) {
+ i++;
+ }
+ }
+ }
+ }
+ new_argv->push_back(0);
+}
+
+bench_opts_t ParseOpts(int argc, char** argv) {
+ bench_opts_t opts;
+ int opt;
+ int option_index = 0;
+
+ opts.cpu_to_lock = LONG_MAX;
+ opts.num_iterations = 0;
+
+ // To make this parser handle the benchmark options silently:
+ extern int opterr;
+ opterr = 0;
+
+ while ((opt = getopt_long(argc, argv, "c:x:i:a:h", g_long_options, &option_index)) != -1) {
+ if (opt == -1) {
+ break;
+ }
+ switch (opt) {
+ case 'c':
+ if (*optarg) {
+ char* check_null;
+ opts.cpu_to_lock = strtol(optarg, &check_null, 10);
+ if (*check_null) {
+ errx(1, "ERROR: Args %s is not a valid integer.", optarg);
+ }
+ } else {
+ printf("ERROR: no argument specified for bionic_cpu\n");
+ Usage();
+ }
+ break;
+ case 'x':
+ if (*optarg) {
+ opts.xmlpath = optarg;
+ } else {
+ printf("ERROR: no argument specified for bionic_xml\n");
+ Usage();
+ }
+ break;
+ case 'a':
+ if (*optarg) {
+ opts.extra_benchmarks.push_back(optarg);
+ } else {
+ printf("ERROR: no argument specified for bionic_extra\n");
+ Usage();
+ }
+ break;
+ case 'i':
+ if (*optarg){
+ char* check_null;
+ opts.num_iterations = strtol(optarg, &check_null, 10);
+ if (*check_null != '\0' or opts.num_iterations < 0) {
+ errx(1, "ERROR: Args %s is not a valid number of iterations.", optarg);
+ }
+ } else {
+ printf("ERROR: no argument specified for bionic_iterations\n");
+ Usage();
+ }
+ break;
+ case 'h':
+ Usage();
+ break;
+ case '?':
+ break;
+ default:
+ exit(1);
+ }
+ }
+ return opts;
+}
+
+// This is a wrapper for every function call for per-benchmark cpu pinning.
+void LockAndRun(benchmark::State& state, benchmark_func_t func_to_bench, long cpu_to_lock) {
+ if (cpu_to_lock != LONG_MAX) LockToCPU(cpu_to_lock);
+ // To avoid having to link against Google benchmarks in libutil,
+ // benchmarks are kept without parameter information, necessitating this cast.
+ reinterpret_cast<void(*) (benchmark::State&)>(func_to_bench)(state);
+}
+
+args_vector_t* ResolveArgs(args_vector_t* to_populate, std::string args,
+ std::map<std::string, args_vector_t>& args_shorthand) {
+ // args is either a space-separated list of ints or a macro name.
+ // To ease formatting in XML files, args is left and right trimmed.
+ if (args_shorthand.count(args)) {
+ return &args_shorthand[args];
+ }
+ to_populate->push_back(std::vector<int>());
+ std::stringstream sstream(args);
+ std::string argstr;
+ while (sstream >> argstr) {
+ char* check_null;
+ int converted = static_cast<int>(strtol(argstr.c_str(), &check_null, 10));
+ if (*check_null) {
+ errx(1, "ERROR: Args str %s contains an invalid macro or int.", args.c_str());
+ }
+ (*to_populate)[0].push_back(converted);
+ }
+ return to_populate;
+}
+
+void RegisterGoogleBenchmarks(bench_opts_t primary_opts, bench_opts_t secondary_opts,
+ std::string fn_name, args_vector_t* run_args) {
+ if (g_str_to_func.find(fn_name) == g_str_to_func.end()) {
+ errx(1, "ERROR: No benchmark for function %s", fn_name.c_str());
+ }
+ long iterations_to_use = primary_opts.num_iterations ? primary_opts.num_iterations :
+ secondary_opts.num_iterations;
+ int cpu_to_use = INT_MAX;
+ if (primary_opts.cpu_to_lock != INT_MAX) {
+ cpu_to_use = primary_opts.cpu_to_lock;
+
+ } else if (secondary_opts.cpu_to_lock != INT_MAX) {
+ cpu_to_use = secondary_opts.cpu_to_lock;
+ }
+
+ for (std::vector<int> args : (*run_args)) {
+ auto registration = benchmark::RegisterBenchmark(fn_name.c_str(), LockAndRun,
+ g_str_to_func.at(fn_name),
+ cpu_to_use)->Args(args);
+ if (iterations_to_use > 0) {
+ registration->Iterations(iterations_to_use);
+ }
+ }
+}
+
+void RegisterCliBenchmarks(bench_opts_t cmdline_opts,
+ std::map<std::string, args_vector_t>& args_shorthand) {
+ // Register any of the extra benchmarks that were specified in the options.
+ args_vector_t arg_vector;
+ args_vector_t* run_args = &arg_vector;
+ for (std::string extra_fn : cmdline_opts.extra_benchmarks) {
+ android::base::Trim(extra_fn);
+ size_t first_space_pos = extra_fn.find(" ");
+ std::string fn_name = extra_fn.substr(0, first_space_pos);
+ std::string cmd_args;
+ if (first_space_pos != std::string::npos) {
+ cmd_args = extra_fn.substr(extra_fn.find(" ") + 1);
+ } else {
+ cmd_args = "";
+ }
+ run_args = ResolveArgs(run_args, cmd_args, args_shorthand);
+ RegisterGoogleBenchmarks(bench_opts_t(), cmdline_opts, fn_name, run_args);
+
+ run_args = &arg_vector;
+ arg_vector.clear();
+ }
+}
+
+int RegisterXmlBenchmarks(bench_opts_t cmdline_opts,
+ std::map<std::string, args_vector_t>& args_shorthand) {
+ // Structure of the XML file:
+ // - Element "fn" Function to benchmark.
+ // - - Element "iterations" Number of iterations to run. Leaving this blank uses
+ // Google benchmarks' convergence heuristics.
+ // - - Element "cpu" CPU to isolate to, if any.
+ // - - Element "args" Whitespace-separated list of per-function integer arguments, or
+ // one of the macros defined in util.h.
+ tinyxml2::XMLDocument doc;
+ if (doc.LoadFile(cmdline_opts.xmlpath.c_str()) != tinyxml2::XML_SUCCESS) {
+ doc.PrintError();
+ return doc.ErrorID();
+ }
+
+ // Read and register the functions.
+ tinyxml2::XMLNode* fn = doc.FirstChildElement("fn");
+ while (fn) {
+ if (fn == fn->ToComment()) {
+ // Skip comments.
+ fn = fn->NextSibling();
+ continue;
+ }
+
+ auto fn_elem = fn->FirstChildElement("name");
+ if (!fn_elem) {
+ errx(1, "ERROR: Malformed XML entry: missing name element.");
+ }
+ std::string fn_name = fn_elem->GetText();
+ if (fn_name.empty()) {
+ errx(1, "ERROR: Malformed XML entry: error parsing name text.");
+ }
+ auto* xml_args = fn->FirstChildElement("args");
+ args_vector_t arg_vector;
+ args_vector_t* run_args = ResolveArgs(&arg_vector,
+ xml_args ? android::base::Trim(xml_args->GetText()) : "",
+ args_shorthand);
+
+ // XML values for CPU and iterations take precedence over those passed in via CLI.
+ bench_opts_t xml_opts{};
+ auto* num_iterations_elem = fn->FirstChildElement("iterations");
+ if (num_iterations_elem) {
+ int temp;
+ num_iterations_elem->QueryIntText(&temp);
+ xml_opts.num_iterations = temp;
+ } else {
+ xml_opts.num_iterations = 0;
+ }
+ auto* cpu_to_lock_elem = fn->FirstChildElement("cpu");
+ if (cpu_to_lock_elem) {
+ int temp;
+ cpu_to_lock_elem->QueryIntText(&temp);
+ xml_opts.cpu_to_lock = temp;
+ } else {
+ xml_opts.cpu_to_lock = INT_MAX;
+ }
+
+ RegisterGoogleBenchmarks(xml_opts, cmdline_opts, fn_name, run_args);
+
+ fn = fn->NextSibling();
+ }
+ return 0;
+}
+
+std::map<std::string, args_vector_t> GetShorthand() {
+ std::map<std::string, args_vector_t> args_shorthand {
+ {"AT_ALIGNED_TWOBUF", args_vector_t{ {8, 0, 0},
+ {64, 0, 0},
+ {512, 0, 0},
+ {1 * KB, 0, 0},
+ {8 * KB, 0, 0},
+ {16 * KB, 0, 0},
+ {32 * KB, 0, 0},
+ {64 * KB, 0, 0} }},
+ {"AT_ALIGNED_ONEBUF", args_vector_t{ {(8), 0},
+ {(64), 0},
+ {(512), 0},
+ {(1*KB), 0},
+ {(8*KB), 0},
+ {(16*KB), 0},
+ {(32*KB), 0},
+ {(64*KB), 0}}},
+
+ {"AT_COMMON_SIZES", args_vector_t{ {8}, {64}, {512}, {1*KB}, {8*KB}, {16*KB},
+ {32*KB}, {64*KB}}},
+
+ // Do not exceed 512. that is about the largest number of properties
+ // that can be created with the current property area size.
+ {"NUM_PROPS", args_vector_t{ {1}, {4}, {16}, {64}, {128}, {256}, {512} }},
+
+ {"MATH_COMMON", args_vector_t{ {0}, {1}, {2}, {3} }}
+ };
+ for (int i = 1; i < 15; i++) {
+ int align = pow(2, i);
+ std::stringstream sstream;
+ sstream << "AT_" << align << "_ALIGN_TWOBUF";
+ args_shorthand.emplace(sstream.str(),
+ args_vector_t{ {8, align, align},
+ {64, align, align},
+ {512, align, align},
+ {1 * KB, align, align},
+ {8 * KB, align, align},
+ {16 * KB, align, align},
+ {32 * KB, align, align},
+ {64 * KB, align, align} });
+ sstream.str("");
+ sstream << "AT_" << align << "_ALIGN_ONEBUF";
+ args_shorthand.emplace(sstream.str(),
+ args_vector_t{ {(8), align},
+ {(64), align},
+ {(512), align},
+ {(1*KB), align},
+ {(8*KB), align},
+ {(16*KB), align},
+ {(32*KB), align},
+ {(64*KB), align} });
+ sstream.str("");
+ }
+ return args_shorthand;
+}
+
+static bool FileExists(const std::string& file) {
+ struct stat st;
+ return stat(file.c_str(), &st) != -1 && S_ISREG(st.st_mode);
+}
+
+int main(int argc, char** argv) {
+ std::map<std::string, args_vector_t> args_shorthand = GetShorthand();
+ bench_opts_t opts = ParseOpts(argc, argv);
+ std::vector<char*> new_argv(argc);
+ SanitizeOpts(argc, argv, &new_argv);
+
+ if (opts.xmlpath.empty()) {
+ // Don't add the default xml file if a user is specifying the tests to run.
+ if (opts.extra_benchmarks.empty()) {
+ // Try and use the default.
+ opts.xmlpath = android::base::GetExecutableDirectory() + "/suites/" + kDefaultSuite;
+ if (!FileExists(opts.xmlpath)) {
+ printf("Cannot find default xml file %s\n", kDefaultSuite);
+ return 1;
+ }
+ }
+ } else if (!FileExists(opts.xmlpath)) {
+ // See if this is a file in the suites directory.
+ std::string file(android::base::GetExecutableDirectory() + "/suites/" + opts.xmlpath);
+ if (opts.xmlpath[0] == '/' || !FileExists(file)) {
+ printf("Cannot find xml file %s: does not exist or is not a file.\n", opts.xmlpath.c_str());
+ return 1;
+ }
+ opts.xmlpath = file;
+ }
+
+ if (!opts.xmlpath.empty()) {
+ if (int err = RegisterXmlBenchmarks(opts, args_shorthand)) {
+ return err;
+ }
+ }
+ RegisterCliBenchmarks(opts, args_shorthand);
+
+ // Set the thread priority to the maximum.
+ if (setpriority(PRIO_PROCESS, 0, -20)) {
+ perror("Failed to raise priority of process. Are you root?\n");
+ }
+
+ int new_argc = new_argv.size();
+ benchmark::Initialize(&new_argc, new_argv.data());
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/benchmarks/math_benchmark.cpp b/benchmarks/math_benchmark.cpp
index a411c9c..7b9a283 100644
--- a/benchmarks/math_benchmark.cpp
+++ b/benchmarks/math_benchmark.cpp
@@ -18,11 +18,11 @@
#include <math.h>
#include <benchmark/benchmark.h>
+#include "util.h"
static const double values[] = { 1234.0, nan(""), HUGE_VAL, 0.0 };
static const char* names[] = { "1234.0", "nan", "HUGE_VAL", "0.0" };
-#define BENCHMARK_COMMON_VALS(name) BENCHMARK(name)->Arg(0)->Arg(1)->Arg(2)->Arg(3)
static void SetLabel(benchmark::State& state) {
state.SetLabel(names[state.range(0)]);
@@ -39,7 +39,7 @@
d += sqrt(v);
}
}
-BENCHMARK(BM_math_sqrt);
+BIONIC_BENCHMARK(BM_math_sqrt);
static void BM_math_log10(benchmark::State& state) {
d = 0.0;
@@ -48,7 +48,7 @@
d += log10(v);
}
}
-BENCHMARK(BM_math_log10);
+BIONIC_BENCHMARK(BM_math_log10);
static void BM_math_logb(benchmark::State& state) {
d = 0.0;
@@ -57,7 +57,7 @@
d += logb(v);
}
}
-BENCHMARK(BM_math_logb);
+BIONIC_BENCHMARK(BM_math_logb);
static void BM_math_isfinite_macro(benchmark::State& state) {
d = 0.0;
@@ -67,7 +67,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_isfinite_macro);
+BIONIC_BENCHMARK(BM_math_isfinite_macro);
#if defined(__BIONIC__)
#define test_isfinite __isfinite
@@ -82,7 +82,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_isfinite);
+BIONIC_BENCHMARK(BM_math_isfinite);
static void BM_math_isinf_macro(benchmark::State& state) {
d = 0.0;
@@ -92,7 +92,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_isinf_macro);
+BIONIC_BENCHMARK(BM_math_isinf_macro);
static void BM_math_isinf(benchmark::State& state) {
d = 0.0;
@@ -102,7 +102,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_isinf);
+BIONIC_BENCHMARK(BM_math_isinf);
static void BM_math_isnan_macro(benchmark::State& state) {
d = 0.0;
@@ -112,7 +112,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_isnan_macro);
+BIONIC_BENCHMARK(BM_math_isnan_macro);
static void BM_math_isnan(benchmark::State& state) {
d = 0.0;
@@ -122,7 +122,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_isnan);
+BIONIC_BENCHMARK(BM_math_isnan);
static void BM_math_isnormal_macro(benchmark::State& state) {
d = 0.0;
@@ -132,7 +132,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_isnormal_macro);
+BIONIC_BENCHMARK(BM_math_isnormal_macro);
#if defined(__BIONIC__)
static void BM_math_isnormal(benchmark::State& state) {
@@ -143,7 +143,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_isnormal);
+BIONIC_BENCHMARK(BM_math_isnormal);
#endif
static void BM_math_sin_fast(benchmark::State& state) {
@@ -152,7 +152,7 @@
d += sin(d);
}
}
-BENCHMARK(BM_math_sin_fast);
+BIONIC_BENCHMARK(BM_math_sin_fast);
static void BM_math_sin_feupdateenv(benchmark::State& state) {
d = 1.0;
@@ -164,7 +164,7 @@
feupdateenv(&__libc_save_rm);
}
}
-BENCHMARK(BM_math_sin_feupdateenv);
+BIONIC_BENCHMARK(BM_math_sin_feupdateenv);
static void BM_math_sin_fesetenv(benchmark::State& state) {
d = 1.0;
@@ -176,7 +176,7 @@
fesetenv(&__libc_save_rm);
}
}
-BENCHMARK(BM_math_sin_fesetenv);
+BIONIC_BENCHMARK(BM_math_sin_fesetenv);
static void BM_math_fpclassify(benchmark::State& state) {
d = 0.0;
@@ -186,7 +186,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_fpclassify);
+BIONIC_BENCHMARK(BM_math_fpclassify);
static void BM_math_signbit_macro(benchmark::State& state) {
d = 0.0;
@@ -196,7 +196,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_signbit_macro);
+BIONIC_BENCHMARK(BM_math_signbit_macro);
static void BM_math_signbit(benchmark::State& state) {
d = 0.0;
@@ -206,7 +206,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_signbit);
+BIONIC_BENCHMARK(BM_math_signbit);
static void BM_math_fabs_macro(benchmark::State& state) {
d = 0.0;
@@ -216,7 +216,7 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_fabs_macro);
+BIONIC_BENCHMARK(BM_math_fabs_macro);
static void BM_math_fabs(benchmark::State& state) {
d = 0.0;
@@ -226,4 +226,4 @@
}
SetLabel(state);
}
-BENCHMARK_COMMON_VALS(BM_math_fabs);
+BIONIC_BENCHMARK(BM_math_fabs);
diff --git a/benchmarks/property_benchmark.cpp b/benchmarks/property_benchmark.cpp
index 97eb832..a099494 100644
--- a/benchmarks/property_benchmark.cpp
+++ b/benchmarks/property_benchmark.cpp
@@ -27,11 +27,7 @@
#include <sys/_system_properties.h>
#include <benchmark/benchmark.h>
-
-// Do not exceed 512, that is about the largest number of properties
-// that can be created with the current property area size.
-#define TEST_NUM_PROPS \
- Arg(1)->Arg(4)->Arg(16)->Arg(64)->Arg(128)->Arg(256)->Arg(512)
+#include "util.h"
struct LocalPropertyTestState {
explicit LocalPropertyTestState(int nprops) : nprops(nprops), valid(false) {
@@ -145,7 +141,7 @@
__system_property_get(pa.names[random() % nprops], value);
}
}
-BENCHMARK(BM_property_get)->TEST_NUM_PROPS;
+BIONIC_BENCHMARK(BM_property_get);
static void BM_property_find(benchmark::State& state) {
const size_t nprops = state.range(0);
@@ -157,7 +153,7 @@
__system_property_find(pa.names[random() % nprops]);
}
}
-BENCHMARK(BM_property_find)->TEST_NUM_PROPS;
+BIONIC_BENCHMARK(BM_property_find);
static void BM_property_read(benchmark::State& state) {
const size_t nprops = state.range(0);
@@ -180,7 +176,7 @@
delete[] pinfo;
}
-BENCHMARK(BM_property_read)->TEST_NUM_PROPS;
+BIONIC_BENCHMARK(BM_property_read);
static void BM_property_serial(benchmark::State& state) {
const size_t nprops = state.range(0);
@@ -201,6 +197,6 @@
delete[] pinfo;
}
-BENCHMARK(BM_property_serial)->TEST_NUM_PROPS;
+BIONIC_BENCHMARK(BM_property_serial);
#endif // __BIONIC__
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index d3c2de8..7a967ef 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -17,6 +17,7 @@
#include <pthread.h>
#include <benchmark/benchmark.h>
+#include "util.h"
// Stop GCC optimizing out our pure function.
/* Must not be static! */ pthread_t (*pthread_self_fp)() = pthread_self;
@@ -26,7 +27,7 @@
pthread_self_fp();
}
}
-BENCHMARK(BM_pthread_self);
+BIONIC_BENCHMARK(BM_pthread_self);
static void BM_pthread_getspecific(benchmark::State& state) {
pthread_key_t key;
@@ -38,7 +39,7 @@
pthread_key_delete(key);
}
-BENCHMARK(BM_pthread_getspecific);
+BIONIC_BENCHMARK(BM_pthread_getspecific);
static void BM_pthread_setspecific(benchmark::State& state) {
pthread_key_t key;
@@ -50,7 +51,7 @@
pthread_key_delete(key);
}
-BENCHMARK(BM_pthread_setspecific);
+BIONIC_BENCHMARK(BM_pthread_setspecific);
static void DummyPthreadOnceInitFunction() {
}
@@ -63,7 +64,7 @@
pthread_once(&once, DummyPthreadOnceInitFunction);
}
}
-BENCHMARK(BM_pthread_once);
+BIONIC_BENCHMARK(BM_pthread_once);
static void BM_pthread_mutex_lock(benchmark::State& state) {
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -73,7 +74,7 @@
pthread_mutex_unlock(&mutex);
}
}
-BENCHMARK(BM_pthread_mutex_lock);
+BIONIC_BENCHMARK(BM_pthread_mutex_lock);
static void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) {
pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
@@ -83,7 +84,7 @@
pthread_mutex_unlock(&mutex);
}
}
-BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
+BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) {
pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
@@ -93,7 +94,7 @@
pthread_mutex_unlock(&mutex);
}
}
-BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
+BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
static void BM_pthread_rwlock_read(benchmark::State& state) {
pthread_rwlock_t lock;
@@ -106,7 +107,7 @@
pthread_rwlock_destroy(&lock);
}
-BENCHMARK(BM_pthread_rwlock_read);
+BIONIC_BENCHMARK(BM_pthread_rwlock_read);
static void BM_pthread_rwlock_write(benchmark::State& state) {
pthread_rwlock_t lock;
@@ -119,7 +120,7 @@
pthread_rwlock_destroy(&lock);
}
-BENCHMARK(BM_pthread_rwlock_write);
+BIONIC_BENCHMARK(BM_pthread_rwlock_write);
static void* IdleThread(void*) {
return NULL;
@@ -134,7 +135,7 @@
state.ResumeTiming();
}
}
-BENCHMARK(BM_pthread_create);
+BIONIC_BENCHMARK(BM_pthread_create);
static void* RunThread(void* arg) {
benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg);
@@ -150,7 +151,7 @@
state.ResumeTiming();
}
}
-BENCHMARK(BM_pthread_create_and_run);
+BIONIC_BENCHMARK(BM_pthread_create_and_run);
static void* ExitThread(void* arg) {
benchmark::State& state = *reinterpret_cast<benchmark::State*>(arg);
@@ -166,7 +167,7 @@
pthread_join(thread, NULL);
}
}
-BENCHMARK(BM_pthread_exit_and_join);
+BIONIC_BENCHMARK(BM_pthread_exit_and_join);
static void BM_pthread_key_create(benchmark::State& state) {
while (state.KeepRunning()) {
@@ -178,7 +179,7 @@
state.ResumeTiming();
}
}
-BENCHMARK(BM_pthread_key_create);
+BIONIC_BENCHMARK(BM_pthread_key_create);
static void BM_pthread_key_delete(benchmark::State& state) {
while (state.KeepRunning()) {
@@ -190,4 +191,4 @@
pthread_key_delete(key);
}
}
-BENCHMARK(BM_pthread_key_delete);
+BIONIC_BENCHMARK(BM_pthread_key_delete);
diff --git a/benchmarks/run-on-host.sh b/benchmarks/run-on-host.sh
index bc63628..af96b27 100755
--- a/benchmarks/run-on-host.sh
+++ b/benchmarks/run-on-host.sh
@@ -12,7 +12,7 @@
)
exit 0
elif [ "$1" != 32 -a "$1" != 64 ]; then
- echo "Usage: $0 [ 32 | 64 | glibc ] [gtest flags]"
+ echo "Usage: $0 [ 32 | 64 | glibc ] [benchmark flags]"
exit 1
fi
diff --git a/benchmarks/semaphore_benchmark.cpp b/benchmarks/semaphore_benchmark.cpp
index b932a2b3..a4aa7bb 100644
--- a/benchmarks/semaphore_benchmark.cpp
+++ b/benchmarks/semaphore_benchmark.cpp
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <benchmark/benchmark.h>
+#include "util.h"
static void BM_semaphore_sem_getvalue(benchmark::State& state) {
sem_t semaphore;
@@ -31,7 +32,7 @@
sem_getvalue(&semaphore, &dummy);
}
}
-BENCHMARK(BM_semaphore_sem_getvalue);
+BIONIC_BENCHMARK(BM_semaphore_sem_getvalue);
static void BM_semaphore_sem_wait_sem_post(benchmark::State& state) {
sem_t semaphore;
@@ -42,7 +43,7 @@
sem_post(&semaphore);
}
}
-BENCHMARK(BM_semaphore_sem_wait_sem_post);
+BIONIC_BENCHMARK(BM_semaphore_sem_wait_sem_post);
// This test reports the overhead of the underlying futex wake syscall on
// the producer. It does not report the overhead from issuing the wake to the
@@ -119,7 +120,9 @@
bool setup = false;
};
-BENCHMARK_F(SemaphoreFixture, semaphore_sem_post)(benchmark::State& state) {
+// This is commented out because dynamic benchmark registering doesn't currently support fixtures.
+// Uncomment it and recompile to run this benchmark on every run.
+/* BENCHMARK_F(SemaphoreFixture, semaphore_sem_post)(benchmark::State& state) {
while (state.KeepRunning()) {
state.PauseTiming();
@@ -149,4 +152,4 @@
param.sched_priority = 0;
sched_setscheduler(0, SCHED_IDLE, ¶m);
}
-}
+}*/
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index f496779..0e7f668 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -14,23 +14,30 @@
* limitations under the License.
*/
+#include <err.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
+#include <android-base/test_utils.h>
#include <benchmark/benchmark.h>
+#include "util.h"
-constexpr auto KB = 1024;
+static void FillFile(TemporaryFile& tf) {
+ char line[256];
+ memset(line, 'x', sizeof(line));
+ line[sizeof(line) - 1] = '\0';
-#define AT_COMMON_SIZES \
- Arg(1)->Arg(2)->Arg(3)->Arg(4)->Arg(8)->Arg(16)->Arg(32)->Arg(64)->Arg(512)-> \
- Arg(1*KB)->Arg(4*KB)->Arg(8*KB)->Arg(16*KB)->Arg(64*KB)
+ FILE* fp = fopen(tf.path, "w");
+ for (size_t i = 0; i < 4096; ++i) fputs(line, fp);
+ fclose(fp);
+}
template <typename Fn>
void ReadWriteTest(benchmark::State& state, Fn f, bool buffered) {
size_t chunk_size = state.range(0);
- FILE* fp = fopen("/dev/zero", "rw");
+ FILE* fp = fopen("/dev/zero", "r+e");
__fsetlocking(fp, FSETLOCKING_BYCALLER);
char* buf = new char[chunk_size];
@@ -39,7 +46,9 @@
}
while (state.KeepRunning()) {
- f(buf, chunk_size, 1, fp);
+ if (f(buf, chunk_size, 1, fp) != 1) {
+ errx(1, "ERROR: op of %zu bytes failed.", chunk_size);
+ }
}
state.SetBytesProcessed(int64_t(state.iterations()) * int64_t(chunk_size));
@@ -50,29 +59,57 @@
void BM_stdio_fread(benchmark::State& state) {
ReadWriteTest(state, fread, true);
}
-BENCHMARK(BM_stdio_fread)->AT_COMMON_SIZES;
+BIONIC_BENCHMARK(BM_stdio_fread);
void BM_stdio_fwrite(benchmark::State& state) {
ReadWriteTest(state, fwrite, true);
}
-BENCHMARK(BM_stdio_fwrite)->AT_COMMON_SIZES;
+BIONIC_BENCHMARK(BM_stdio_fwrite);
void BM_stdio_fread_unbuffered(benchmark::State& state) {
ReadWriteTest(state, fread, false);
}
-BENCHMARK(BM_stdio_fread_unbuffered)->AT_COMMON_SIZES;
+BIONIC_BENCHMARK(BM_stdio_fread_unbuffered);
void BM_stdio_fwrite_unbuffered(benchmark::State& state) {
ReadWriteTest(state, fwrite, false);
}
-BENCHMARK(BM_stdio_fwrite_unbuffered)->AT_COMMON_SIZES;
+BIONIC_BENCHMARK(BM_stdio_fwrite_unbuffered);
+
+#if !defined(__GLIBC__)
+static void FopenFgetlnFclose(benchmark::State& state, bool no_locking) {
+ TemporaryFile tf;
+ FillFile(tf);
+ while (state.KeepRunning()) {
+ FILE* fp = fopen(tf.path, "re");
+ if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ size_t length;
+ while (fgetln(fp, &length) != nullptr) {
+ }
+ fclose(fp);
+ }
+}
+
+static void BM_stdio_fopen_fgetln_fclose_locking(benchmark::State& state) {
+ FopenFgetlnFclose(state, false);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetln_fclose_locking);
+
+void BM_stdio_fopen_fgetln_fclose_no_locking(benchmark::State& state) {
+ FopenFgetlnFclose(state, true);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetln_fclose_no_locking);
+#endif
static void FopenFgetsFclose(benchmark::State& state, bool no_locking) {
- char buf[1024];
+ TemporaryFile tf;
+ FillFile(tf);
+ char buf[BUFSIZ];
while (state.KeepRunning()) {
- FILE* fp = fopen("/proc/version", "re");
+ FILE* fp = fopen(tf.path, "re");
if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
- if (fgets(buf, sizeof(buf), fp) == nullptr) abort();
+ while (fgets(buf, sizeof(buf), fp) != nullptr) {
+ }
fclose(fp);
}
}
@@ -80,9 +117,57 @@
static void BM_stdio_fopen_fgets_fclose_locking(benchmark::State& state) {
FopenFgetsFclose(state, false);
}
-BENCHMARK(BM_stdio_fopen_fgets_fclose_locking);
+BIONIC_BENCHMARK(BM_stdio_fopen_fgets_fclose_locking);
void BM_stdio_fopen_fgets_fclose_no_locking(benchmark::State& state) {
FopenFgetsFclose(state, true);
}
-BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking);
+BIONIC_BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking);
+
+static void FopenGetlineFclose(benchmark::State& state, bool no_locking) {
+ TemporaryFile tf;
+ FillFile(tf);
+ while (state.KeepRunning()) {
+ FILE* fp = fopen(tf.path, "re");
+ if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ char* line = nullptr;
+ size_t n = 0;
+ while (getline(&line, &n, fp) != -1) {
+ }
+ free(line);
+ fclose(fp);
+ }
+}
+
+static void BM_stdio_fopen_getline_fclose_locking(benchmark::State& state) {
+ FopenGetlineFclose(state, false);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_getline_fclose_locking);
+
+void BM_stdio_fopen_getline_fclose_no_locking(benchmark::State& state) {
+ FopenGetlineFclose(state, true);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_getline_fclose_no_locking);
+
+static void FopenFgetcFclose(benchmark::State& state, bool no_locking) {
+ size_t nbytes = state.range(0);
+ while (state.KeepRunning()) {
+ FILE* fp = fopen("/dev/zero", "re");
+ if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ volatile int c __attribute__((unused));
+ for (size_t i = 0; i < nbytes; ++i) {
+ c = fgetc(fp);
+ }
+ fclose(fp);
+ }
+}
+
+static void BM_stdio_fopen_fgetc_fclose_locking(benchmark::State& state) {
+ FopenFgetcFclose(state, false);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetc_fclose_locking);
+
+void BM_stdio_fopen_fgetc_fclose_no_locking(benchmark::State& state) {
+ FopenFgetcFclose(state, true);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetc_fclose_no_locking);
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
new file mode 100644
index 0000000..eb325ab
--- /dev/null
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <err.h>
+#include <langinfo.h>
+#include <locale.h>
+#include <stdlib.h>
+
+#include <benchmark/benchmark.h>
+#include "util.h"
+
+static void BM_stdlib_malloc_free(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+
+ void* c;
+ while (state.KeepRunning()) {
+ c = malloc(nbytes);
+ free(c);
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BIONIC_BENCHMARK(BM_stdlib_malloc_free);
+
+static void BM_stdlib_mbstowcs(benchmark::State& state) {
+ const size_t buf_alignment = state.range(0);
+ const size_t widebuf_alignment = state.range(1);
+
+ std::vector<char> buf;
+ std::vector<wchar_t> widebuf;
+
+ setlocale(LC_CTYPE, "C.UTF-8")
+ || setlocale(LC_CTYPE, "en_US.UTF-8")
+ || setlocale(LC_CTYPE, "en_GB.UTF-8")
+ || setlocale(LC_CTYPE, "en.UTF-8")
+ || setlocale(LC_CTYPE, "de_DE-8")
+ || setlocale(LC_CTYPE, "fr_FR-8");
+ if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
+ errx(1, "ERROR: unable to set locale in BM_stdlib_mbstowcs");
+ }
+
+ char* buf_aligned = GetAlignedPtr(&buf, buf_alignment, 500000);
+ wchar_t* widebuf_aligned = GetAlignedPtr(&widebuf, widebuf_alignment, 500000);
+ size_t i, j, k, l;
+ l = 0;
+ for (i=0xc3; i<0xe0; i++)
+ for (j=0x80; j<0xc0; j++)
+ buf[l++] = i, buf[l++] = j;
+ for (i=0xe1; i<0xed; i++)
+ for (j=0x80; j<0xc0; j++)
+ for (k=0x80; k<0xc0; k++)
+ buf[l++] = i, buf[l++] = j, buf[l++] = k;
+ for (i=0xf1; i<0xf4; i++)
+ for (j=0x80; j<0xc0; j++)
+ for (k=0x80; k<0xc0; k++)
+ buf[l++] = i, buf[l++] = j, buf[l++] = 0x80, buf[l++] = k;
+ buf[l++] = 0;
+
+ volatile size_t c __attribute__((unused)) = 0;
+ while (state.KeepRunning()) {
+ c = mbstowcs(widebuf_aligned, buf_aligned, 500000);
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(500000));
+}
+BIONIC_BENCHMARK(BM_stdlib_mbstowcs);
+
+static void BM_stdlib_mbrtowc(benchmark::State& state) {
+ const size_t buf_alignment = state.range(0);
+
+ std::vector<char> buf;
+
+ setlocale(LC_CTYPE, "C.UTF-8")
+ || setlocale(LC_CTYPE, "en_US.UTF-8")
+ || setlocale(LC_CTYPE, "en_GB.UTF-8")
+ || setlocale(LC_CTYPE, "en.UTF-8")
+ || setlocale(LC_CTYPE, "de_DE-8")
+ || setlocale(LC_CTYPE, "fr_FR-8");
+ if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
+ errx(1, "ERROR: unable to set locale in BM_stdlib_mbrtowc");
+ }
+
+ char* buf_aligned = GetAlignedPtr(&buf, buf_alignment, 500000);
+ size_t i, j, k, l;
+ l = 0;
+ for (i=0xc3; i<0xe0; i++)
+ for (j=0x80; j<0xc0; j++)
+ buf[l++] = i, buf[l++] = j;
+ for (i=0xe1; i<0xed; i++)
+ for (j=0x80; j<0xc0; j++)
+ for (k=0x80; k<0xc0; k++)
+ buf[l++] = i, buf[l++] = j, buf[l++] = k;
+ for (i=0xf1; i<0xf4; i++)
+ for (j=0x80; j<0xc0; j++)
+ for (k=0x80; k<0xc0; k++)
+ buf[l++] = i, buf[l++] = j, buf[l++] = 0x80, buf[l++] = k;
+ buf[l++] = 0;
+
+ wchar_t wc = 0;
+ while (state.KeepRunning()) {
+ for (j = 0; buf_aligned[j]; j+=mbrtowc(&wc, buf_aligned + j, 4, NULL)) {
+ }
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(500000));
+}
+BIONIC_BENCHMARK(BM_stdlib_mbrtowc);
diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp
index 2ab65a8..eb04c93 100644
--- a/benchmarks/string_benchmark.cpp
+++ b/benchmarks/string_benchmark.cpp
@@ -14,31 +14,12 @@
* limitations under the License.
*/
+#include <err.h>
#include <stdint.h>
#include <string.h>
#include <benchmark/benchmark.h>
-#include "util.h"
-
-constexpr auto KB = 1024;
-
-// NOTE: these constants are temporary replacements for AT_COMMON_SIZES until
-// the new interface for Bionic benchmarks is implemented.
-
-// Set all four to 0 to test normal alignment.
-#define AT_SRC_ALIGN 0
-#define AT_DST_ALIGN 0
-
-#define AT_ALIGNED_TWOBUF \
- Args({(8), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(64), AT_SRC_ALIGN, AT_DST_ALIGN})-> \
- Args({(512), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(1*KB), AT_SRC_ALIGN, AT_DST_ALIGN})-> \
- Args({(8*KB), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(16*KB), AT_SRC_ALIGN, AT_DST_ALIGN})-> \
- Args({(32*KB), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(64*KB), AT_SRC_ALIGN, AT_DST_ALIGN})
-
-#define AT_ALIGNED_ONEBUF \
- Args({(8), AT_SRC_ALIGN})->Args({(64), AT_SRC_ALIGN})->Args({(512), AT_SRC_ALIGN})-> \
- Args({(1*KB), AT_SRC_ALIGN})->Args({(8*KB), AT_SRC_ALIGN})->Args({(16*KB), AT_SRC_ALIGN})-> \
- Args({(32*KB), AT_SRC_ALIGN})->Args({(64*KB), AT_SRC_ALIGN})
+#include <util.h>
static void BM_string_memcmp(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -57,7 +38,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_memcmp)->AT_ALIGNED_TWOBUF;
+BIONIC_BENCHMARK(BM_string_memcmp);
static void BM_string_memcpy(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -75,7 +56,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_memcpy)->AT_ALIGNED_TWOBUF;
+BIONIC_BENCHMARK(BM_string_memcpy);
static void BM_string_memmove_non_overlapping(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -93,7 +74,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_memmove_non_overlapping)->AT_ALIGNED_TWOBUF;
+BIONIC_BENCHMARK(BM_string_memmove_non_overlapping);
static void BM_string_memmove_overlap_dst_before_src(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -108,7 +89,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_memmove_overlap_dst_before_src)->AT_ALIGNED_ONEBUF;
+BIONIC_BENCHMARK(BM_string_memmove_overlap_dst_before_src);
static void BM_string_memmove_overlap_src_before_dst(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -123,7 +104,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_memmove_overlap_src_before_dst)->AT_ALIGNED_ONEBUF;
+BIONIC_BENCHMARK(BM_string_memmove_overlap_src_before_dst);
static void BM_string_memset(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -138,7 +119,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_memset)->AT_ALIGNED_ONEBUF;
+BIONIC_BENCHMARK(BM_string_memset);
static void BM_string_strlen(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -155,7 +136,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_strlen)->AT_ALIGNED_ONEBUF;
+BIONIC_BENCHMARK(BM_string_strlen);
static void BM_string_strcat_copy_only(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -178,7 +159,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_strcat_copy_only)->AT_ALIGNED_TWOBUF;
+BIONIC_BENCHMARK(BM_string_strcat_copy_only);
static void BM_string_strcat_seek_only(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -199,7 +180,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_strcat_seek_only)->AT_ALIGNED_TWOBUF;
+BIONIC_BENCHMARK(BM_string_strcat_seek_only);
static void BM_string_strcat_half_copy_half_seek(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -220,7 +201,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_strcat_half_copy_half_seek)->AT_ALIGNED_TWOBUF;
+BIONIC_BENCHMARK(BM_string_strcat_half_copy_half_seek);
static void BM_string_strcpy(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -239,7 +220,7 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_strcpy)->AT_ALIGNED_TWOBUF;
+BIONIC_BENCHMARK(BM_string_strcpy);
static void BM_string_strcmp(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -260,4 +241,51 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
-BENCHMARK(BM_string_strcmp)->AT_ALIGNED_TWOBUF;
+BIONIC_BENCHMARK(BM_string_strcmp);
+
+static void BM_string_strstr(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ const size_t haystack_alignment = state.range(1);
+ const size_t needle_alignment = state.range(2);
+
+ std::vector<char> haystack;
+ std::vector<char> needle;
+ char* haystack_aligned = GetAlignedPtrFilled(&haystack, haystack_alignment, nbytes, 'x');
+ char* needle_aligned = GetAlignedPtrFilled(&needle, needle_alignment,
+ std::min(nbytes, static_cast<size_t>(5)), 'x');
+
+ if (nbytes / 4 > 2) {
+ for (size_t i = 0; nbytes / 4 >= 2 && i < nbytes / 4 - 2; i++) {
+ haystack_aligned[4 * i + 3] = 'y';
+ }
+ }
+ haystack_aligned[nbytes - 1] = '\0';
+ needle_aligned[needle.size() - 1] = '\0';
+
+ while (state.KeepRunning()) {
+ if (strstr(haystack_aligned, needle_aligned) == nullptr) {
+ errx(1, "ERROR: strstr failed to find valid substring.");
+ }
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BIONIC_BENCHMARK(BM_string_strstr);
+
+static void BM_string_strchr(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ const size_t haystack_alignment = state.range(1);
+
+ std::vector<char> haystack;
+ char* haystack_aligned = GetAlignedPtrFilled(&haystack, haystack_alignment, nbytes, 'x');
+ haystack_aligned[nbytes-1] = '\0';
+
+ while (state.KeepRunning()) {
+ if (strchr(haystack_aligned, 'y') != nullptr) {
+ errx(1, "ERROR: strchr found a chr where it should have failed.");
+ }
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BIONIC_BENCHMARK(BM_string_strchr);
diff --git a/benchmarks/suites/full.xml b/benchmarks/suites/full.xml
new file mode 100644
index 0000000..a7bd9d4
--- /dev/null
+++ b/benchmarks/suites/full.xml
@@ -0,0 +1,311 @@
+<fn>
+ <name>BM_empty</name>
+</fn>
+<fn>
+ <name>BM_load_relaxed</name>
+</fn>
+<fn>
+ <name>BM_load_acquire</name>
+</fn>
+<fn>
+ <name>BM_store_release</name>
+</fn>
+<fn>
+ <name>BM_store_seq_cst</name>
+</fn>
+<fn>
+ <name>BM_fetch_add_relaxed</name>
+</fn>
+<fn>
+ <name>BM_fetch_add_seq_cst</name>
+</fn>
+<fn>
+ <name>BM_acquire_fence</name>
+</fn>
+<fn>
+ <name>BM_seq_cst_fence</name>
+</fn>
+<fn>
+ <name>BM_fetch_add_cs</name>
+</fn>
+<fn>
+ <name>BM_math_sqrt</name>
+</fn>
+<fn>
+ <name>BM_math_log10</name>
+</fn>
+<fn>
+ <name>BM_math_logb</name>
+</fn>
+<fn>
+ <name>BM_math_isfinite_macro</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_isfinite</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_isinf_macro</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_isinf</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_isnan_macro</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_isnan</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_isnormal_macro</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_isnormal</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_sin_fast</name>
+</fn>
+<fn>
+ <name>BM_math_sin_feupdateenv</name>
+</fn>
+<fn>
+ <name>BM_math_sin_fesetenv</name>
+</fn>
+<fn>
+ <name>BM_math_fpclassify</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_signbit_macro</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_signbit</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_fabs_macro</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_math_fabs</name>
+ <args>MATH_COMMON</args>
+</fn>
+<fn>
+ <name>BM_pthread_self</name>
+</fn>
+<fn>
+ <name>BM_pthread_getspecific</name>
+</fn>
+<fn>
+ <name>BM_pthread_setspecific</name>
+</fn>
+<fn>
+ <name>BM_pthread_once</name>
+</fn>
+<fn>
+ <name>BM_pthread_mutex_lock</name>
+</fn>
+<fn>
+ <name>BM_pthread_mutex_lock_ERRORCHECK</name>
+</fn>
+<fn>
+ <name>BM_pthread_mutex_lock_RECURSIVE</name>
+</fn>
+<fn>
+ <name>BM_pthread_rwlock_read</name>
+</fn>
+<fn>
+ <name>BM_pthread_rwlock_write</name>
+</fn>
+<fn>
+ <name>BM_pthread_create</name>
+</fn>
+<fn>
+ <name>BM_pthread_create_and_run</name>
+</fn>
+<fn>
+ <name>BM_pthread_exit_and_join</name>
+</fn>
+<fn>
+ <name>BM_pthread_key_create</name>
+</fn>
+<fn>
+ <name>BM_pthread_key_delete</name>
+</fn>
+<fn>
+ <name>BM_semaphore_sem_getvalue</name>
+</fn>
+<fn>
+ <name>BM_semaphore_sem_wait_sem_post</name>
+</fn>
+<fn>
+ <name>BM_stdio_fread</name>
+ <args>AT_COMMON_SIZES</args>
+</fn>
+<fn>
+ <name>BM_stdio_fwrite</name>
+ <args>AT_COMMON_SIZES</args>
+</fn>
+<fn>
+ <name>BM_stdio_fread_unbuffered</name>
+ <args>AT_COMMON_SIZES</args>
+</fn>
+<fn>
+ <name>BM_stdio_fwrite_unbuffered</name>
+ <args>AT_COMMON_SIZES</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetln_fclose_locking</name>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetln_fclose_no_locking</name>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgets_fclose_locking</name>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgets_fclose_no_locking</name>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_no_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_getline_fclose_locking</name>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_getline_fclose_no_locking</name>
+</fn>
+<fn>
+ <name>BM_string_memcmp</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memcpy</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memmove_non_overlapping</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memmove_overlap_dst_before_src</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memmove_overlap_src_before_dst</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memset</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strlen</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcat_copy_only</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcat_seek_only</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcat_half_copy_half_seek</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcpy</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcmp</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strstr</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strchr</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_time_clock_gettime</name>
+</fn>
+<fn>
+ <name>BM_time_clock_gettime_syscall</name>
+</fn>
+<fn>
+ <name>BM_time_gettimeofday</name>
+</fn>
+<fn>
+ <name>BM_time_gettimeofday_syscall</name>
+</fn>
+<fn>
+ <name>BM_time_time</name>
+</fn>
+<fn>
+ <name>BM_time_localtime</name>
+</fn>
+<fn>
+ <name>BM_time_localtime_r</name>
+</fn>
+<fn>
+ <name>BM_unistd_getpid</name>
+</fn>
+<fn>
+ <name>BM_unistd_getpid_syscall</name>
+</fn>
+<fn>
+ <name>BM_unistd_gettid</name>
+</fn>
+<fn>
+ <name>BM_unistd_gettid_syscall</name>
+</fn>
+<fn>
+ <name>BM_stdlib_malloc_free</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbstowcs</name>
+ <args>0 0</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbrtowc</name>
+ <args>0</args>
+</fn>
+<!--
+ Put the property tests at the end since they might cause segfaults in
+ tests running afterwards (b/62197783).
+-->
+<fn>
+ <name>BM_property_get</name>
+ <args>NUM_PROPS</args>
+</fn>
+<fn>
+ <name>BM_property_find</name>
+ <args>NUM_PROPS</args>
+</fn>
+<fn>
+ <name>BM_property_read</name>
+ <args>NUM_PROPS</args>
+</fn>
+<fn>
+ <name>BM_property_serial</name>
+ <args>NUM_PROPS</args>
+</fn>
diff --git a/benchmarks/suites/host.xml b/benchmarks/suites/host.xml
new file mode 100644
index 0000000..05769e9
--- /dev/null
+++ b/benchmarks/suites/host.xml
@@ -0,0 +1,274 @@
+<fn>
+ <name>BM_empty</name>
+</fn>
+<fn>
+ <name>BM_load_relaxed</name>
+</fn>
+<fn>
+ <name>BM_load_acquire</name>
+</fn>
+<fn>
+ <name>BM_store_release</name>
+</fn>
+<fn>
+ <name>BM_store_seq_cst</name>
+</fn>
+<fn>
+ <name>BM_fetch_add_relaxed</name>
+</fn>
+<fn>
+ <name>BM_fetch_add_seq_cst</name>
+</fn>
+<fn>
+ <name>BM_acquire_fence</name>
+</fn>
+<fn>
+ <name>BM_seq_cst_fence</name>
+</fn>
+<fn>
+ <name>BM_fetch_add_cs</name>
+</fn>
+<fn>
+ <name>BM_math_sqrt</name>
+</fn>
+<fn>
+ <name>BM_math_log10</name>
+</fn>
+<fn>
+ <name>BM_math_logb</name>
+</fn>
+<fn>
+ <name>BM_math_isfinite_macro</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_isfinite</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_isinf_macro</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_isinf</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_isnan_macro</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_isnan</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_isnormal_macro</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_sin_fast</name>
+</fn>
+<fn>
+ <name>BM_math_sin_feupdateenv</name>
+</fn>
+<fn>
+ <name>BM_math_sin_fesetenv</name>
+</fn>
+<fn>
+ <name>BM_math_fpclassify</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_signbit_macro</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_signbit</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_fabs_macro</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_math_fabs</name>
+ <args>0</args>
+</fn>
+<fn>
+ <name>BM_pthread_self</name>
+</fn>
+<fn>
+ <name>BM_pthread_getspecific</name>
+</fn>
+<fn>
+ <name>BM_pthread_setspecific</name>
+</fn>
+<fn>
+ <name>BM_pthread_once</name>
+</fn>
+<fn>
+ <name>BM_pthread_mutex_lock</name>
+</fn>
+<fn>
+ <name>BM_pthread_mutex_lock_ERRORCHECK</name>
+</fn>
+<fn>
+ <name>BM_pthread_mutex_lock_RECURSIVE</name>
+</fn>
+<fn>
+ <name>BM_pthread_rwlock_read</name>
+</fn>
+<fn>
+ <name>BM_pthread_rwlock_write</name>
+</fn>
+<fn>
+ <name>BM_pthread_create</name>
+</fn>
+<fn>
+ <name>BM_pthread_create_and_run</name>
+</fn>
+<fn>
+ <name>BM_pthread_exit_and_join</name>
+</fn>
+<fn>
+ <name>BM_pthread_key_create</name>
+</fn>
+<fn>
+ <name>BM_pthread_key_delete</name>
+</fn>
+<fn>
+ <name>BM_semaphore_sem_getvalue</name>
+</fn>
+<fn>
+ <name>BM_semaphore_sem_wait_sem_post</name>
+</fn>
+<fn>
+ <name>BM_stdio_fread</name>
+ <args>AT_COMMON_SIZES</args>
+</fn>
+<fn>
+ <name>BM_stdio_fwrite</name>
+ <args>AT_COMMON_SIZES</args>
+</fn>
+<fn>
+ <name>BM_stdio_fread_unbuffered</name>
+ <args>AT_COMMON_SIZES</args>
+</fn>
+<fn>
+ <name>BM_stdio_fwrite_unbuffered</name>
+ <args>AT_COMMON_SIZES</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgets_fclose_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgets_fclose_no_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_no_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_string_memcmp</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memcpy</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memmove_non_overlapping</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memmove_overlap_dst_before_src</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memmove_overlap_src_before_dst</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memset</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strlen</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcat_copy_only</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcat_seek_only</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcat_half_copy_half_seek</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcpy</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strcmp</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strstr</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strchr</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_time_clock_gettime</name>
+</fn>
+<fn>
+ <name>BM_time_clock_gettime_syscall</name>
+</fn>
+<fn>
+ <name>BM_time_gettimeofday</name>
+</fn>
+<fn>
+ <name>BM_time_gettimeofday_syscall</name>
+</fn>
+<fn>
+ <name>BM_time_time</name>
+</fn>
+<fn>
+ <name>BM_time_localtime</name>
+</fn>
+<fn>
+ <name>BM_time_localtime_r</name>
+</fn>
+<fn>
+ <name>BM_unistd_getpid</name>
+</fn>
+<fn>
+ <name>BM_unistd_getpid_syscall</name>
+</fn>
+<fn>
+ <name>BM_unistd_gettid_syscall</name>
+</fn>
+<fn>
+ <name>BM_stdlib_malloc_free</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbstowcs</name>
+ <args>0 0</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbrtowc</name>
+ <args>0</args>
+</fn>
diff --git a/benchmarks/test_suites/test_alignment.xml b/benchmarks/test_suites/test_alignment.xml
new file mode 100644
index 0000000..20df320
--- /dev/null
+++ b/benchmarks/test_suites/test_alignment.xml
@@ -0,0 +1,50 @@
+<fn>
+ <name>BM_string_memcmp</name>
+ <iterations>1</iterations>
+ <args>AT_2_ALIGN_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memcmp</name>
+ <iterations>1</iterations>
+ <args>AT_4_ALIGN_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memcmp</name>
+ <iterations>1</iterations>
+ <args>AT_16_ALIGN_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memcmp</name>
+ <iterations>1</iterations>
+ <args>AT_512_ALIGN_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_memcmp</name>
+ <iterations>1</iterations>
+ <args>AT_2048_ALIGN_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strlen</name>
+ <iterations>1</iterations>
+ <args>AT_2_ALIGN_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strlen</name>
+ <iterations>1</iterations>
+ <args>AT_4_ALIGN_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strlen</name>
+ <iterations>1</iterations>
+ <args>AT_16_ALIGN_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strlen</name>
+ <iterations>1</iterations>
+ <args>AT_512_ALIGN_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strlen</name>
+ <iterations>1</iterations>
+ <args>AT_2048_ALIGN_ONEBUF</args>
+</fn>
diff --git a/benchmarks/test_suites/test_from_each.xml b/benchmarks/test_suites/test_from_each.xml
new file mode 100644
index 0000000..0118365
--- /dev/null
+++ b/benchmarks/test_suites/test_from_each.xml
@@ -0,0 +1,30 @@
+<fn>
+ <name>BM_empty</name>
+</fn>
+<fn>
+ <name>BM_math_sqrt</name>
+</fn>
+<fn>
+ <name>BM_property_get</name>
+ <args>1</args>
+</fn>
+<fn>
+ <name>BM_pthread_self</name>
+</fn>
+<fn>
+ <name>BM_semaphore_sem_getvalue</name>
+</fn>
+<fn>
+ <name>BM_stdio_fread</name>
+ <args>64</args>
+</fn>
+<fn>
+ <name>BM_string_memcpy</name>
+ <args>512 4 4</args>
+</fn>
+<fn>
+ <name>BM_time_clock_gettime</name>
+</fn>
+<fn>
+ <name>BM_unistd_getpid</name>
+</fn>
diff --git a/benchmarks/test_suites/test_medium.xml b/benchmarks/test_suites/test_medium.xml
new file mode 100644
index 0000000..9528af3
--- /dev/null
+++ b/benchmarks/test_suites/test_medium.xml
@@ -0,0 +1,16 @@
+<fn>
+ <name>BM_string_memcmp</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_math_sqrt</name>
+</fn>
+<fn>
+ <name>BM_string_memcpy</name>
+ <iterations>25</iterations>
+ <args>512 4 4</args>
+</fn>
+<fn>
+ <name>BM_property_get</name>
+ <args>1</args>
+</fn>
diff --git a/benchmarks/test_suites/test_small.xml b/benchmarks/test_suites/test_small.xml
new file mode 100644
index 0000000..a4cc285
--- /dev/null
+++ b/benchmarks/test_suites/test_small.xml
@@ -0,0 +1,11 @@
+<fn>
+ <name>BM_string_memcmp</name>
+ <args>8 8 8</args>
+</fn>
+<fn>
+ <name>BM_math_sqrt</name>
+</fn>
+<fn>
+ <name>BM_property_get</name>
+ <args>1</args>
+</fn>
diff --git a/benchmarks/tests/interface_test.cpp b/benchmarks/tests/interface_test.cpp
new file mode 100644
index 0000000..b8279b6
--- /dev/null
+++ b/benchmarks/tests/interface_test.cpp
@@ -0,0 +1,630 @@
+/*
+ * 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 <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <regex>
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <gtest/gtest.h>
+
+class SystemTests : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ raw_output_ = "";
+ sanitized_output_ = "";
+ exitcode_ = 0;
+ }
+
+ void SanitizeOutput();
+
+ void Exec(std::vector<const char*> args);
+ void RunTest(std::vector<const char*> extra_args = {});
+ void Verify(const std::string& expected_output, int expected_exitcode,
+ std::vector<const char*> extra_args = {}, bool sanitize = true);
+
+ std::string raw_output_;
+ std::string sanitized_output_;
+ int exitcode_;
+ pid_t pid_;
+ int fd_;
+};
+
+static std::string GetBionicXmlArg(const char* xml_file) {
+ return "--bionic_xml=" + android::base::GetExecutableDirectory() + "/test_suites/" + xml_file;
+}
+
+void SystemTests::SanitizeOutput() {
+ // Cut off anything after the arguments, since that varies with time.
+ sanitized_output_ = std::regex_replace(raw_output_, std::regex(".+(BM_\\S+) +.+"), "$1");
+
+ // Remove everything before the header.
+ sanitized_output_.erase(0, sanitized_output_.find("------------------------------------------------"));
+
+ // Remove the header.
+ sanitized_output_.erase(0, sanitized_output_.find("BM_"));
+
+ // Remove any hanging output.
+ sanitized_output_.erase(sanitized_output_.find_last_of("BM_\\S+\n") + 1);
+}
+
+static void GetExe(std::string* exe_name) {
+ char path[PATH_MAX];
+ ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path));
+ ASSERT_TRUE(path_len >= 0);
+ *exe_name = std::string(std::regex_replace(path, std::regex("-tests"), ""));
+}
+
+void SystemTests::Exec(std::vector<const char*> args) {
+ int fds[2];
+ ASSERT_NE(-1, pipe(fds));
+ ASSERT_NE(-1, fcntl(fds[0], F_SETFL, O_NONBLOCK));
+
+ if ((pid_ = fork()) == 0) {
+ // Run the test.
+ close(fds[0]);
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ ASSERT_NE(0, dup2(fds[1], STDOUT_FILENO));
+ ASSERT_NE(0, dup2(fds[1], STDERR_FILENO));
+ close(fds[1]);
+
+ std::string exe_name;
+ GetExe(&exe_name);
+ args.insert(args.begin(), exe_name.c_str());
+ args.push_back(nullptr);
+ execv(args[0], reinterpret_cast<char* const*>(const_cast<char**>(args.data())));
+ exit(1);
+ }
+ ASSERT_NE(-1, pid_);
+
+ close(fds[1]);
+ fd_ = fds[0];
+}
+
+void SystemTests::Verify(const std::string& expected_output,
+ int expected_exitcode, std::vector<const char*> extra_args, bool sanitize) {
+ std::vector<const char*> args;
+ for (const auto& arg : extra_args) {
+ args.push_back(arg);
+ }
+
+ Exec(args);
+
+ raw_output_ = "";
+ while (true) {
+ char buffer[4097];
+ ssize_t bytes = TEMP_FAILURE_RETRY(read(fd_, buffer, sizeof(buffer) - 1));
+ if (bytes == -1 && errno == EAGAIN) {
+ continue;
+ }
+ ASSERT_NE(-1, bytes);
+ if (bytes == 0) {
+ break;
+ }
+ buffer[bytes] = '\0';
+ raw_output_ += buffer;
+ }
+ close(fd_);
+
+ int status;
+ ASSERT_EQ(pid_, TEMP_FAILURE_RETRY(waitpid(pid_, &status, 0))) << "Test output:\n" << raw_output_;
+ exitcode_ = WEXITSTATUS(status);
+ ASSERT_EQ(expected_exitcode, exitcode_) << "Test output:\n" << raw_output_;
+
+ if (sanitize) {
+ SanitizeOutput();
+ ASSERT_EQ(expected_output, sanitized_output_);
+ } else {
+ ASSERT_EQ(expected_output, raw_output_);
+ }
+}
+
+TEST_F(SystemTests, help) {
+ std::string expected =
+ "Usage:\n"
+ "bionic_benchmarks [--bionic_cpu=<cpu_to_isolate>]\n"
+ " [--bionic_xml=<path_to_xml>]\n"
+ " [--bionic_iterations=<num_iter>]\n"
+ " [--bionic_extra=\"<fn_name> <arg1> <arg 2> ...\"]\n"
+ " [<Google benchmark flags>]\n"
+ "Google benchmark flags:\n"
+ "benchmark [--benchmark_list_tests={true|false}]\n"
+ " [--benchmark_filter=<regex>]\n"
+ " [--benchmark_min_time=<min_time>]\n"
+ " [--benchmark_repetitions=<num_repetitions>]\n"
+ " [--benchmark_report_aggregates_only={true|false}\n"
+ " [--benchmark_format=<console|json|csv>]\n"
+ " [--benchmark_out=<filename>]\n"
+ " [--benchmark_out_format=<json|console|csv>]\n"
+ " [--benchmark_color={auto|true|false}]\n"
+ " [--benchmark_counters_tabular={true|false}]\n"
+ " [--v=<verbosity>]\n";
+ Verify(expected, 0, std::vector<const char*>{"--help"}, false);
+}
+
+TEST_F(SystemTests, full_suite) {
+ std::string expected =
+ "BM_empty/iterations:1\n"
+ "BM_load_relaxed/iterations:1\n"
+ "BM_load_acquire/iterations:1\n"
+ "BM_store_release/iterations:1\n"
+ "BM_store_seq_cst/iterations:1\n"
+ "BM_fetch_add_relaxed/iterations:1\n"
+ "BM_fetch_add_seq_cst/iterations:1\n"
+ "BM_acquire_fence/iterations:1\n"
+ "BM_seq_cst_fence/iterations:1\n"
+ "BM_fetch_add_cs/iterations:1\n"
+ "BM_math_sqrt/iterations:1\n"
+ "BM_math_log10/iterations:1\n"
+ "BM_math_logb/iterations:1\n"
+ "BM_math_isfinite_macro/0/iterations:1\n"
+ "BM_math_isfinite_macro/1/iterations:1\n"
+ "BM_math_isfinite_macro/2/iterations:1\n"
+ "BM_math_isfinite_macro/3/iterations:1\n"
+ "BM_math_isfinite/0/iterations:1\n"
+ "BM_math_isfinite/1/iterations:1\n"
+ "BM_math_isfinite/2/iterations:1\n"
+ "BM_math_isfinite/3/iterations:1\n"
+ "BM_math_isinf_macro/0/iterations:1\n"
+ "BM_math_isinf_macro/1/iterations:1\n"
+ "BM_math_isinf_macro/2/iterations:1\n"
+ "BM_math_isinf_macro/3/iterations:1\n"
+ "BM_math_isinf/0/iterations:1\n"
+ "BM_math_isinf/1/iterations:1\n"
+ "BM_math_isinf/2/iterations:1\n"
+ "BM_math_isinf/3/iterations:1\n"
+ "BM_math_isnan_macro/0/iterations:1\n"
+ "BM_math_isnan_macro/1/iterations:1\n"
+ "BM_math_isnan_macro/2/iterations:1\n"
+ "BM_math_isnan_macro/3/iterations:1\n"
+ "BM_math_isnan/0/iterations:1\n"
+ "BM_math_isnan/1/iterations:1\n"
+ "BM_math_isnan/2/iterations:1\n"
+ "BM_math_isnan/3/iterations:1\n"
+ "BM_math_isnormal_macro/0/iterations:1\n"
+ "BM_math_isnormal_macro/1/iterations:1\n"
+ "BM_math_isnormal_macro/2/iterations:1\n"
+ "BM_math_isnormal_macro/3/iterations:1\n"
+ "BM_math_isnormal/0/iterations:1\n"
+ "BM_math_isnormal/1/iterations:1\n"
+ "BM_math_isnormal/2/iterations:1\n"
+ "BM_math_isnormal/3/iterations:1\n"
+ "BM_math_sin_fast/iterations:1\n"
+ "BM_math_sin_feupdateenv/iterations:1\n"
+ "BM_math_sin_fesetenv/iterations:1\n"
+ "BM_math_fpclassify/0/iterations:1\n"
+ "BM_math_fpclassify/1/iterations:1\n"
+ "BM_math_fpclassify/2/iterations:1\n"
+ "BM_math_fpclassify/3/iterations:1\n"
+ "BM_math_signbit_macro/0/iterations:1\n"
+ "BM_math_signbit_macro/1/iterations:1\n"
+ "BM_math_signbit_macro/2/iterations:1\n"
+ "BM_math_signbit_macro/3/iterations:1\n"
+ "BM_math_signbit/0/iterations:1\n"
+ "BM_math_signbit/1/iterations:1\n"
+ "BM_math_signbit/2/iterations:1\n"
+ "BM_math_signbit/3/iterations:1\n"
+ "BM_math_fabs_macro/0/iterations:1\n"
+ "BM_math_fabs_macro/1/iterations:1\n"
+ "BM_math_fabs_macro/2/iterations:1\n"
+ "BM_math_fabs_macro/3/iterations:1\n"
+ "BM_math_fabs/0/iterations:1\n"
+ "BM_math_fabs/1/iterations:1\n"
+ "BM_math_fabs/2/iterations:1\n"
+ "BM_math_fabs/3/iterations:1\n"
+ "BM_pthread_self/iterations:1\n"
+ "BM_pthread_getspecific/iterations:1\n"
+ "BM_pthread_setspecific/iterations:1\n"
+ "BM_pthread_once/iterations:1\n"
+ "BM_pthread_mutex_lock/iterations:1\n"
+ "BM_pthread_mutex_lock_ERRORCHECK/iterations:1\n"
+ "BM_pthread_mutex_lock_RECURSIVE/iterations:1\n"
+ "BM_pthread_rwlock_read/iterations:1\n"
+ "BM_pthread_rwlock_write/iterations:1\n"
+ "BM_pthread_create/iterations:1\n"
+ "BM_pthread_create_and_run/iterations:1\n"
+ "BM_pthread_exit_and_join/iterations:1\n"
+ "BM_pthread_key_create/iterations:1\n"
+ "BM_pthread_key_delete/iterations:1\n"
+ "BM_semaphore_sem_getvalue/iterations:1\n"
+ "BM_semaphore_sem_wait_sem_post/iterations:1\n"
+ "BM_stdio_fread/8/iterations:1\n"
+ "BM_stdio_fread/64/iterations:1\n"
+ "BM_stdio_fread/512/iterations:1\n"
+ "BM_stdio_fread/1024/iterations:1\n"
+ "BM_stdio_fread/8192/iterations:1\n"
+ "BM_stdio_fread/16384/iterations:1\n"
+ "BM_stdio_fread/32768/iterations:1\n"
+ "BM_stdio_fread/65536/iterations:1\n"
+ "BM_stdio_fwrite/8/iterations:1\n"
+ "BM_stdio_fwrite/64/iterations:1\n"
+ "BM_stdio_fwrite/512/iterations:1\n"
+ "BM_stdio_fwrite/1024/iterations:1\n"
+ "BM_stdio_fwrite/8192/iterations:1\n"
+ "BM_stdio_fwrite/16384/iterations:1\n"
+ "BM_stdio_fwrite/32768/iterations:1\n"
+ "BM_stdio_fwrite/65536/iterations:1\n"
+ "BM_stdio_fread_unbuffered/8/iterations:1\n"
+ "BM_stdio_fread_unbuffered/64/iterations:1\n"
+ "BM_stdio_fread_unbuffered/512/iterations:1\n"
+ "BM_stdio_fread_unbuffered/1024/iterations:1\n"
+ "BM_stdio_fread_unbuffered/8192/iterations:1\n"
+ "BM_stdio_fread_unbuffered/16384/iterations:1\n"
+ "BM_stdio_fread_unbuffered/32768/iterations:1\n"
+ "BM_stdio_fread_unbuffered/65536/iterations:1\n"
+ "BM_stdio_fwrite_unbuffered/8/iterations:1\n"
+ "BM_stdio_fwrite_unbuffered/64/iterations:1\n"
+ "BM_stdio_fwrite_unbuffered/512/iterations:1\n"
+ "BM_stdio_fwrite_unbuffered/1024/iterations:1\n"
+ "BM_stdio_fwrite_unbuffered/8192/iterations:1\n"
+ "BM_stdio_fwrite_unbuffered/16384/iterations:1\n"
+ "BM_stdio_fwrite_unbuffered/32768/iterations:1\n"
+ "BM_stdio_fwrite_unbuffered/65536/iterations:1\n"
+ "BM_stdio_fopen_fgetln_fclose_locking/iterations:1\n"
+ "BM_stdio_fopen_fgetln_fclose_no_locking/iterations:1\n"
+ "BM_stdio_fopen_fgets_fclose_locking/iterations:1\n"
+ "BM_stdio_fopen_fgets_fclose_no_locking/iterations:1\n"
+ "BM_stdio_fopen_fgetc_fclose_locking/1024/iterations:1\n"
+ "BM_stdio_fopen_fgetc_fclose_no_locking/1024/iterations:1\n"
+ "BM_stdio_fopen_getline_fclose_locking/iterations:1\n"
+ "BM_stdio_fopen_getline_fclose_no_locking/iterations:1\n"
+ "BM_string_memcmp/8/0/0/iterations:1\n"
+ "BM_string_memcmp/64/0/0/iterations:1\n"
+ "BM_string_memcmp/512/0/0/iterations:1\n"
+ "BM_string_memcmp/1024/0/0/iterations:1\n"
+ "BM_string_memcmp/8192/0/0/iterations:1\n"
+ "BM_string_memcmp/16384/0/0/iterations:1\n"
+ "BM_string_memcmp/32768/0/0/iterations:1\n"
+ "BM_string_memcmp/65536/0/0/iterations:1\n"
+ "BM_string_memcpy/8/0/0/iterations:1\n"
+ "BM_string_memcpy/64/0/0/iterations:1\n"
+ "BM_string_memcpy/512/0/0/iterations:1\n"
+ "BM_string_memcpy/1024/0/0/iterations:1\n"
+ "BM_string_memcpy/8192/0/0/iterations:1\n"
+ "BM_string_memcpy/16384/0/0/iterations:1\n"
+ "BM_string_memcpy/32768/0/0/iterations:1\n"
+ "BM_string_memcpy/65536/0/0/iterations:1\n"
+ "BM_string_memmove_non_overlapping/8/0/0/iterations:1\n"
+ "BM_string_memmove_non_overlapping/64/0/0/iterations:1\n"
+ "BM_string_memmove_non_overlapping/512/0/0/iterations:1\n"
+ "BM_string_memmove_non_overlapping/1024/0/0/iterations:1\n"
+ "BM_string_memmove_non_overlapping/8192/0/0/iterations:1\n"
+ "BM_string_memmove_non_overlapping/16384/0/0/iterations:1\n"
+ "BM_string_memmove_non_overlapping/32768/0/0/iterations:1\n"
+ "BM_string_memmove_non_overlapping/65536/0/0/iterations:1\n"
+ "BM_string_memmove_overlap_dst_before_src/8/0/iterations:1\n"
+ "BM_string_memmove_overlap_dst_before_src/64/0/iterations:1\n"
+ "BM_string_memmove_overlap_dst_before_src/512/0/iterations:1\n"
+ "BM_string_memmove_overlap_dst_before_src/1024/0/iterations:1\n"
+ "BM_string_memmove_overlap_dst_before_src/8192/0/iterations:1\n"
+ "BM_string_memmove_overlap_dst_before_src/16384/0/iterations:1\n"
+ "BM_string_memmove_overlap_dst_before_src/32768/0/iterations:1\n"
+ "BM_string_memmove_overlap_dst_before_src/65536/0/iterations:1\n"
+ "BM_string_memmove_overlap_src_before_dst/8/0/iterations:1\n"
+ "BM_string_memmove_overlap_src_before_dst/64/0/iterations:1\n"
+ "BM_string_memmove_overlap_src_before_dst/512/0/iterations:1\n"
+ "BM_string_memmove_overlap_src_before_dst/1024/0/iterations:1\n"
+ "BM_string_memmove_overlap_src_before_dst/8192/0/iterations:1\n"
+ "BM_string_memmove_overlap_src_before_dst/16384/0/iterations:1\n"
+ "BM_string_memmove_overlap_src_before_dst/32768/0/iterations:1\n"
+ "BM_string_memmove_overlap_src_before_dst/65536/0/iterations:1\n"
+ "BM_string_memset/8/0/iterations:1\n"
+ "BM_string_memset/64/0/iterations:1\n"
+ "BM_string_memset/512/0/iterations:1\n"
+ "BM_string_memset/1024/0/iterations:1\n"
+ "BM_string_memset/8192/0/iterations:1\n"
+ "BM_string_memset/16384/0/iterations:1\n"
+ "BM_string_memset/32768/0/iterations:1\n"
+ "BM_string_memset/65536/0/iterations:1\n"
+ "BM_string_strlen/8/0/iterations:1\n"
+ "BM_string_strlen/64/0/iterations:1\n"
+ "BM_string_strlen/512/0/iterations:1\n"
+ "BM_string_strlen/1024/0/iterations:1\n"
+ "BM_string_strlen/8192/0/iterations:1\n"
+ "BM_string_strlen/16384/0/iterations:1\n"
+ "BM_string_strlen/32768/0/iterations:1\n"
+ "BM_string_strlen/65536/0/iterations:1\n"
+ "BM_string_strcat_copy_only/8/0/0/iterations:1\n"
+ "BM_string_strcat_copy_only/64/0/0/iterations:1\n"
+ "BM_string_strcat_copy_only/512/0/0/iterations:1\n"
+ "BM_string_strcat_copy_only/1024/0/0/iterations:1\n"
+ "BM_string_strcat_copy_only/8192/0/0/iterations:1\n"
+ "BM_string_strcat_copy_only/16384/0/0/iterations:1\n"
+ "BM_string_strcat_copy_only/32768/0/0/iterations:1\n"
+ "BM_string_strcat_copy_only/65536/0/0/iterations:1\n"
+ "BM_string_strcat_seek_only/8/0/0/iterations:1\n"
+ "BM_string_strcat_seek_only/64/0/0/iterations:1\n"
+ "BM_string_strcat_seek_only/512/0/0/iterations:1\n"
+ "BM_string_strcat_seek_only/1024/0/0/iterations:1\n"
+ "BM_string_strcat_seek_only/8192/0/0/iterations:1\n"
+ "BM_string_strcat_seek_only/16384/0/0/iterations:1\n"
+ "BM_string_strcat_seek_only/32768/0/0/iterations:1\n"
+ "BM_string_strcat_seek_only/65536/0/0/iterations:1\n"
+ "BM_string_strcat_half_copy_half_seek/8/0/0/iterations:1\n"
+ "BM_string_strcat_half_copy_half_seek/64/0/0/iterations:1\n"
+ "BM_string_strcat_half_copy_half_seek/512/0/0/iterations:1\n"
+ "BM_string_strcat_half_copy_half_seek/1024/0/0/iterations:1\n"
+ "BM_string_strcat_half_copy_half_seek/8192/0/0/iterations:1\n"
+ "BM_string_strcat_half_copy_half_seek/16384/0/0/iterations:1\n"
+ "BM_string_strcat_half_copy_half_seek/32768/0/0/iterations:1\n"
+ "BM_string_strcat_half_copy_half_seek/65536/0/0/iterations:1\n"
+ "BM_string_strcpy/8/0/0/iterations:1\n"
+ "BM_string_strcpy/64/0/0/iterations:1\n"
+ "BM_string_strcpy/512/0/0/iterations:1\n"
+ "BM_string_strcpy/1024/0/0/iterations:1\n"
+ "BM_string_strcpy/8192/0/0/iterations:1\n"
+ "BM_string_strcpy/16384/0/0/iterations:1\n"
+ "BM_string_strcpy/32768/0/0/iterations:1\n"
+ "BM_string_strcpy/65536/0/0/iterations:1\n"
+ "BM_string_strcmp/8/0/0/iterations:1\n"
+ "BM_string_strcmp/64/0/0/iterations:1\n"
+ "BM_string_strcmp/512/0/0/iterations:1\n"
+ "BM_string_strcmp/1024/0/0/iterations:1\n"
+ "BM_string_strcmp/8192/0/0/iterations:1\n"
+ "BM_string_strcmp/16384/0/0/iterations:1\n"
+ "BM_string_strcmp/32768/0/0/iterations:1\n"
+ "BM_string_strcmp/65536/0/0/iterations:1\n"
+ "BM_string_strstr/8/0/0/iterations:1\n"
+ "BM_string_strstr/64/0/0/iterations:1\n"
+ "BM_string_strstr/512/0/0/iterations:1\n"
+ "BM_string_strstr/1024/0/0/iterations:1\n"
+ "BM_string_strstr/8192/0/0/iterations:1\n"
+ "BM_string_strstr/16384/0/0/iterations:1\n"
+ "BM_string_strstr/32768/0/0/iterations:1\n"
+ "BM_string_strstr/65536/0/0/iterations:1\n"
+ "BM_string_strchr/8/0/iterations:1\n"
+ "BM_string_strchr/64/0/iterations:1\n"
+ "BM_string_strchr/512/0/iterations:1\n"
+ "BM_string_strchr/1024/0/iterations:1\n"
+ "BM_string_strchr/8192/0/iterations:1\n"
+ "BM_string_strchr/16384/0/iterations:1\n"
+ "BM_string_strchr/32768/0/iterations:1\n"
+ "BM_string_strchr/65536/0/iterations:1\n"
+ "BM_time_clock_gettime/iterations:1\n"
+ "BM_time_clock_gettime_syscall/iterations:1\n"
+ "BM_time_gettimeofday/iterations:1\n"
+ "BM_time_gettimeofday_syscall/iterations:1\n"
+ "BM_time_time/iterations:1\n"
+ "BM_time_localtime/iterations:1\n"
+ "BM_time_localtime_r/iterations:1\n"
+ "BM_unistd_getpid/iterations:1\n"
+ "BM_unistd_getpid_syscall/iterations:1\n"
+ "BM_unistd_gettid/iterations:1\n"
+ "BM_unistd_gettid_syscall/iterations:1\n"
+ "BM_stdlib_malloc_free/8/0/iterations:1\n"
+ "BM_stdlib_malloc_free/64/0/iterations:1\n"
+ "BM_stdlib_malloc_free/512/0/iterations:1\n"
+ "BM_stdlib_malloc_free/1024/0/iterations:1\n"
+ "BM_stdlib_malloc_free/8192/0/iterations:1\n"
+ "BM_stdlib_malloc_free/16384/0/iterations:1\n"
+ "BM_stdlib_malloc_free/32768/0/iterations:1\n"
+ "BM_stdlib_malloc_free/65536/0/iterations:1\n"
+ "BM_stdlib_mbstowcs/0/0/iterations:1\n"
+ "BM_stdlib_mbrtowc/0/iterations:1\n"
+ "BM_property_get/1/iterations:1\n"
+ "BM_property_get/4/iterations:1\n"
+ "BM_property_get/16/iterations:1\n"
+ "BM_property_get/64/iterations:1\n"
+ "BM_property_get/128/iterations:1\n"
+ "BM_property_get/256/iterations:1\n"
+ "BM_property_get/512/iterations:1\n"
+ "BM_property_find/1/iterations:1\n"
+ "BM_property_find/4/iterations:1\n"
+ "BM_property_find/16/iterations:1\n"
+ "BM_property_find/64/iterations:1\n"
+ "BM_property_find/128/iterations:1\n"
+ "BM_property_find/256/iterations:1\n"
+ "BM_property_find/512/iterations:1\n"
+ "BM_property_read/1/iterations:1\n"
+ "BM_property_read/4/iterations:1\n"
+ "BM_property_read/16/iterations:1\n"
+ "BM_property_read/64/iterations:1\n"
+ "BM_property_read/128/iterations:1\n"
+ "BM_property_read/256/iterations:1\n"
+ "BM_property_read/512/iterations:1\n"
+ "BM_property_serial/1/iterations:1\n"
+ "BM_property_serial/4/iterations:1\n"
+ "BM_property_serial/16/iterations:1\n"
+ "BM_property_serial/64/iterations:1\n"
+ "BM_property_serial/128/iterations:1\n"
+ "BM_property_serial/256/iterations:1\n"
+ "BM_property_serial/512/iterations:1\n";
+ Verify(expected, 0, std::vector<const char*>{"--bionic_iterations=1"});
+
+ // Make sure that the test suite can be found in the suites directory.
+ Verify(expected, 0, std::vector<const char*>{"--bionic_iterations=1", "--bionic_xml=full.xml"});
+}
+
+TEST_F(SystemTests, small) {
+ std::string expected =
+ "BM_string_memcmp/8/8/8/iterations:1\n"
+ "BM_math_sqrt/iterations:1\n"
+ "BM_property_get/1/iterations:1\n";
+ Verify(expected, 0, std::vector<const char*>{GetBionicXmlArg("test_small.xml").c_str(),
+ "--bionic_iterations=1"});
+}
+
+TEST_F(SystemTests, medium) {
+ std::string expected =
+ "BM_string_memcmp/8/0/0/iterations:1\n"
+ "BM_string_memcmp/64/0/0/iterations:1\n"
+ "BM_string_memcmp/512/0/0/iterations:1\n"
+ "BM_string_memcmp/1024/0/0/iterations:1\n"
+ "BM_string_memcmp/8192/0/0/iterations:1\n"
+ "BM_string_memcmp/16384/0/0/iterations:1\n"
+ "BM_string_memcmp/32768/0/0/iterations:1\n"
+ "BM_string_memcmp/65536/0/0/iterations:1\n"
+ "BM_math_sqrt/iterations:1\n"
+ "BM_string_memcpy/512/4/4/iterations:25\n"
+ "BM_property_get/1/iterations:1\n";
+ Verify(expected, 0, std::vector<const char*>{GetBionicXmlArg("test_medium.xml").c_str(),
+ "--bionic_iterations=1"});
+}
+
+TEST_F(SystemTests, from_each) {
+ std::string expected =
+ "BM_empty/iterations:1\n"
+ "BM_math_sqrt/iterations:1\n"
+ "BM_property_get/1/iterations:1\n"
+ "BM_pthread_self/iterations:1\n"
+ "BM_semaphore_sem_getvalue/iterations:1\n"
+ "BM_stdio_fread/64/iterations:1\n"
+ "BM_string_memcpy/512/4/4/iterations:1\n"
+ "BM_time_clock_gettime/iterations:1\n"
+ "BM_unistd_getpid/iterations:1\n";
+ Verify(expected, 0, std::vector<const char*>{GetBionicXmlArg("test_from_each.xml").c_str(),
+ "--bionic_iterations=1"});
+}
+
+TEST_F(SystemTests, cmd_args) {
+ std::string expected =
+ "BM_string_memcpy/8/8/8/iterations:1\n"
+ "BM_math_log10/iterations:1\n";
+ Verify(expected, 0, std::vector<const char*>{"--bionic_extra=BM_string_memcpy 8 8 8",
+ "--bionic_extra=BM_math_log10",
+ "--bionic_iterations=1"});
+}
+
+TEST_F(SystemTests, cmd_args_no_iter) {
+ std::string expected =
+ "BM_string_memcpy/8/8/8\n"
+ "BM_math_log10\n";
+ Verify(expected, 0, std::vector<const char*>{"--bionic_extra=BM_string_memcpy 8 8 8",
+ "--bionic_extra=BM_math_log10"});
+}
+
+TEST_F(SystemTests, xml_and_args) {
+ std::string expected =
+ "BM_string_memcmp/8/0/0/iterations:1\n"
+ "BM_string_memcmp/64/0/0/iterations:1\n"
+ "BM_string_memcmp/512/0/0/iterations:1\n"
+ "BM_string_memcmp/1024/0/0/iterations:1\n"
+ "BM_string_memcmp/8192/0/0/iterations:1\n"
+ "BM_string_memcmp/16384/0/0/iterations:1\n"
+ "BM_string_memcmp/32768/0/0/iterations:1\n"
+ "BM_string_memcmp/65536/0/0/iterations:1\n"
+ "BM_math_sqrt/iterations:1\n"
+ "BM_string_memcpy/512/4/4/iterations:25\n"
+ "BM_property_get/1/iterations:1\n"
+ "BM_string_memcpy/8/0/0/iterations:1\n"
+ "BM_string_memcpy/64/0/0/iterations:1\n"
+ "BM_string_memcpy/512/0/0/iterations:1\n"
+ "BM_string_memcpy/1024/0/0/iterations:1\n"
+ "BM_string_memcpy/8192/0/0/iterations:1\n"
+ "BM_string_memcpy/16384/0/0/iterations:1\n"
+ "BM_string_memcpy/32768/0/0/iterations:1\n"
+ "BM_string_memcpy/65536/0/0/iterations:1\n"
+ "BM_math_log10/iterations:1\n";
+ Verify(expected, 0, std::vector<const char*>{"--bionic_extra=BM_string_memcpy AT_ALIGNED_TWOBUF",
+ "--bionic_extra=BM_math_log10",
+ "--bionic_cpu=0",
+ GetBionicXmlArg("test_medium.xml").c_str(),
+ "--bionic_iterations=1"});
+}
+
+TEST_F(SystemTests, alignment) {
+ std::string expected =
+ "BM_string_memcmp/8/2/2/iterations:1\n"
+ "BM_string_memcmp/64/2/2/iterations:1\n"
+ "BM_string_memcmp/512/2/2/iterations:1\n"
+ "BM_string_memcmp/1024/2/2/iterations:1\n"
+ "BM_string_memcmp/8192/2/2/iterations:1\n"
+ "BM_string_memcmp/16384/2/2/iterations:1\n"
+ "BM_string_memcmp/32768/2/2/iterations:1\n"
+ "BM_string_memcmp/65536/2/2/iterations:1\n"
+ "BM_string_memcmp/8/4/4/iterations:1\n"
+ "BM_string_memcmp/64/4/4/iterations:1\n"
+ "BM_string_memcmp/512/4/4/iterations:1\n"
+ "BM_string_memcmp/1024/4/4/iterations:1\n"
+ "BM_string_memcmp/8192/4/4/iterations:1\n"
+ "BM_string_memcmp/16384/4/4/iterations:1\n"
+ "BM_string_memcmp/32768/4/4/iterations:1\n"
+ "BM_string_memcmp/65536/4/4/iterations:1\n"
+ "BM_string_memcmp/8/16/16/iterations:1\n"
+ "BM_string_memcmp/64/16/16/iterations:1\n"
+ "BM_string_memcmp/512/16/16/iterations:1\n"
+ "BM_string_memcmp/1024/16/16/iterations:1\n"
+ "BM_string_memcmp/8192/16/16/iterations:1\n"
+ "BM_string_memcmp/16384/16/16/iterations:1\n"
+ "BM_string_memcmp/32768/16/16/iterations:1\n"
+ "BM_string_memcmp/65536/16/16/iterations:1\n"
+ "BM_string_memcmp/8/512/512/iterations:1\n"
+ "BM_string_memcmp/64/512/512/iterations:1\n"
+ "BM_string_memcmp/512/512/512/iterations:1\n"
+ "BM_string_memcmp/1024/512/512/iterations:1\n"
+ "BM_string_memcmp/8192/512/512/iterations:1\n"
+ "BM_string_memcmp/16384/512/512/iterations:1\n"
+ "BM_string_memcmp/32768/512/512/iterations:1\n"
+ "BM_string_memcmp/65536/512/512/iterations:1\n"
+ "BM_string_memcmp/8/2048/2048/iterations:1\n"
+ "BM_string_memcmp/64/2048/2048/iterations:1\n"
+ "BM_string_memcmp/512/2048/2048/iterations:1\n"
+ "BM_string_memcmp/1024/2048/2048/iterations:1\n"
+ "BM_string_memcmp/8192/2048/2048/iterations:1\n"
+ "BM_string_memcmp/16384/2048/2048/iterations:1\n"
+ "BM_string_memcmp/32768/2048/2048/iterations:1\n"
+ "BM_string_memcmp/65536/2048/2048/iterations:1\n"
+ "BM_string_strlen/8/2/iterations:1\n"
+ "BM_string_strlen/64/2/iterations:1\n"
+ "BM_string_strlen/512/2/iterations:1\n"
+ "BM_string_strlen/1024/2/iterations:1\n"
+ "BM_string_strlen/8192/2/iterations:1\n"
+ "BM_string_strlen/16384/2/iterations:1\n"
+ "BM_string_strlen/32768/2/iterations:1\n"
+ "BM_string_strlen/65536/2/iterations:1\n"
+ "BM_string_strlen/8/4/iterations:1\n"
+ "BM_string_strlen/64/4/iterations:1\n"
+ "BM_string_strlen/512/4/iterations:1\n"
+ "BM_string_strlen/1024/4/iterations:1\n"
+ "BM_string_strlen/8192/4/iterations:1\n"
+ "BM_string_strlen/16384/4/iterations:1\n"
+ "BM_string_strlen/32768/4/iterations:1\n"
+ "BM_string_strlen/65536/4/iterations:1\n"
+ "BM_string_strlen/8/16/iterations:1\n"
+ "BM_string_strlen/64/16/iterations:1\n"
+ "BM_string_strlen/512/16/iterations:1\n"
+ "BM_string_strlen/1024/16/iterations:1\n"
+ "BM_string_strlen/8192/16/iterations:1\n"
+ "BM_string_strlen/16384/16/iterations:1\n"
+ "BM_string_strlen/32768/16/iterations:1\n"
+ "BM_string_strlen/65536/16/iterations:1\n"
+ "BM_string_strlen/8/512/iterations:1\n"
+ "BM_string_strlen/64/512/iterations:1\n"
+ "BM_string_strlen/512/512/iterations:1\n"
+ "BM_string_strlen/1024/512/iterations:1\n"
+ "BM_string_strlen/8192/512/iterations:1\n"
+ "BM_string_strlen/16384/512/iterations:1\n"
+ "BM_string_strlen/32768/512/iterations:1\n"
+ "BM_string_strlen/65536/512/iterations:1\n"
+ "BM_string_strlen/8/2048/iterations:1\n"
+ "BM_string_strlen/64/2048/iterations:1\n"
+ "BM_string_strlen/512/2048/iterations:1\n"
+ "BM_string_strlen/1024/2048/iterations:1\n"
+ "BM_string_strlen/8192/2048/iterations:1\n"
+ "BM_string_strlen/16384/2048/iterations:1\n"
+ "BM_string_strlen/32768/2048/iterations:1\n"
+ "BM_string_strlen/65536/2048/iterations:1\n";
+ Verify(expected, 0, std::vector<const char*>{GetBionicXmlArg("test_alignment.xml").c_str(),
+ "--bionic_iterations=1"});
+}
diff --git a/benchmarks/time_benchmark.cpp b/benchmarks/time_benchmark.cpp
index c90dfad..4c6d5dd 100644
--- a/benchmarks/time_benchmark.cpp
+++ b/benchmarks/time_benchmark.cpp
@@ -20,6 +20,7 @@
#include <unistd.h>
#include <benchmark/benchmark.h>
+#include "util.h"
static void BM_time_clock_gettime(benchmark::State& state) {
timespec t;
@@ -27,7 +28,7 @@
clock_gettime(CLOCK_MONOTONIC, &t);
}
}
-BENCHMARK(BM_time_clock_gettime);
+BIONIC_BENCHMARK(BM_time_clock_gettime);
static void BM_time_clock_gettime_syscall(benchmark::State& state) {
timespec t;
@@ -35,7 +36,7 @@
syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &t);
}
}
-BENCHMARK(BM_time_clock_gettime_syscall);
+BIONIC_BENCHMARK(BM_time_clock_gettime_syscall);
static void BM_time_gettimeofday(benchmark::State& state) {
timeval tv;
@@ -43,7 +44,7 @@
gettimeofday(&tv, nullptr);
}
}
-BENCHMARK(BM_time_gettimeofday);
+BIONIC_BENCHMARK(BM_time_gettimeofday);
void BM_time_gettimeofday_syscall(benchmark::State& state) {
timeval tv;
@@ -51,14 +52,14 @@
syscall(__NR_gettimeofday, &tv, nullptr);
}
}
-BENCHMARK(BM_time_gettimeofday_syscall);
+BIONIC_BENCHMARK(BM_time_gettimeofday_syscall);
void BM_time_time(benchmark::State& state) {
while (state.KeepRunning()) {
time(nullptr);
}
}
-BENCHMARK(BM_time_time);
+BIONIC_BENCHMARK(BM_time_time);
void BM_time_localtime(benchmark::State& state) {
time_t t = time(nullptr);
@@ -66,7 +67,7 @@
localtime(&t);
}
}
-BENCHMARK(BM_time_localtime);
+BIONIC_BENCHMARK(BM_time_localtime);
void BM_time_localtime_r(benchmark::State& state) {
time_t t = time(nullptr);
@@ -75,4 +76,4 @@
localtime_r(&t, &tm);
}
}
-BENCHMARK(BM_time_localtime_r);
+BIONIC_BENCHMARK(BM_time_localtime_r);
diff --git a/benchmarks/unistd_benchmark.cpp b/benchmarks/unistd_benchmark.cpp
index b78d3eb..98e8858 100644
--- a/benchmarks/unistd_benchmark.cpp
+++ b/benchmarks/unistd_benchmark.cpp
@@ -18,20 +18,21 @@
#include <unistd.h>
#include <benchmark/benchmark.h>
+#include "util.h"
static void BM_unistd_getpid(benchmark::State& state) {
while (state.KeepRunning()) {
getpid();
}
}
-BENCHMARK(BM_unistd_getpid);
+BIONIC_BENCHMARK(BM_unistd_getpid);
static void BM_unistd_getpid_syscall(benchmark::State& state) {
while (state.KeepRunning()) {
syscall(__NR_getpid);
}
}
-BENCHMARK(BM_unistd_getpid_syscall);
+BIONIC_BENCHMARK(BM_unistd_getpid_syscall);
#if defined(__BIONIC__)
@@ -43,7 +44,7 @@
gettid_fp();
}
}
-BENCHMARK(BM_unistd_gettid);
+BIONIC_BENCHMARK(BM_unistd_gettid);
#endif
@@ -52,6 +53,4 @@
syscall(__NR_gettid);
}
}
-BENCHMARK(BM_unistd_gettid_syscall);
-
-BENCHMARK_MAIN()
+BIONIC_BENCHMARK(BM_unistd_gettid_syscall);
diff --git a/benchmarks/util.cpp b/benchmarks/util.cpp
index d9641cf..92e8243 100644
--- a/benchmarks/util.cpp
+++ b/benchmarks/util.cpp
@@ -16,21 +16,22 @@
#include "util.h"
+#include <err.h>
+#include <math.h>
#include <sched.h>
#include <stdio.h>
#include <string.h>
+#include <wchar.h>
+
#include <cstdlib>
-#include <vector>
// This function returns a pointer less than 2 * alignment + or_mask bytes into the array.
-char *GetAlignedMemory(char *orig_ptr, size_t alignment, size_t or_mask) {
+char* GetAlignedMemory(char* orig_ptr, size_t alignment, size_t or_mask) {
if ((alignment & (alignment - 1)) != 0) {
- fprintf(stderr, "warning: alignment passed into GetAlignedMemory is not a power of two.\n");
- std::abort();
+ errx(1, "warning: alignment passed into GetAlignedMemory is not a power of two.");
}
if (or_mask > alignment) {
- fprintf(stderr, "warning: or_mask passed into GetAlignedMemory is too high.\n");
- std::abort();
+ errx(1, "warning: or_mask passed into GetAlignedMemory is too high.");
}
uintptr_t ptr = reinterpret_cast<uintptr_t>(orig_ptr);
if (alignment > 0) {
@@ -44,12 +45,18 @@
return reinterpret_cast<char*>(ptr);
}
-char *GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes) {
+char* GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes) {
buf->resize(nbytes + 3 * alignment);
return GetAlignedMemory(buf->data(), alignment, 0);
}
-char *GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte) {
+wchar_t* GetAlignedPtr(std::vector<wchar_t>* buf, size_t alignment, size_t nchars) {
+ buf->resize(nchars + ceil((3 * alignment) / sizeof(wchar_t)));
+ return reinterpret_cast<wchar_t*>(GetAlignedMemory(reinterpret_cast<char*>(buf->data()),
+ alignment, 0));
+}
+
+char* GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte) {
char* buf_aligned = GetAlignedPtr(buf, alignment, nbytes);
memset(buf_aligned, fill_byte, nbytes);
return buf_aligned;
@@ -64,7 +71,7 @@
#else
-bool LockToCPU(int cpu_to_lock) {
+bool LockToCPU(long cpu_to_lock) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
@@ -81,7 +88,7 @@
}
}
} else if (!CPU_ISSET(cpu_to_lock, &cpuset)) {
- printf("Cpu %d does not exist.\n", cpu_to_lock);
+ printf("Cpu %ld does not exist.\n", cpu_to_lock);
return false;
}
diff --git a/benchmarks/util.h b/benchmarks/util.h
index bd3d515..cf6f50e 100644
--- a/benchmarks/util.h
+++ b/benchmarks/util.h
@@ -17,15 +17,45 @@
#ifndef _BIONIC_BENCHMARKS_UTIL_H_
#define _BIONIC_BENCHMARKS_UTIL_H_
+#include <map>
+#include <mutex>
+#include <string>
#include <vector>
+typedef void (*benchmark_func_t) (void);
+
+extern std::mutex g_map_lock;
+
+extern std::map<std::string, benchmark_func_t> g_str_to_func;
+
+static int __attribute__((unused)) EmplaceBenchmark (std::string fn_name, benchmark_func_t fn_ptr) {
+ g_map_lock.lock();
+ g_str_to_func.emplace(std::string(fn_name), fn_ptr);
+ g_map_lock.unlock();
+ return 0;
+}
+
+#define BIONIC_BENCHMARK(n) \
+ int _bionic_benchmark_##n __attribute__((unused)) = EmplaceBenchmark(std::string(#n), reinterpret_cast<benchmark_func_t>(n))
+
+constexpr auto KB = 1024;
+
+typedef struct {
+ long cpu_to_lock;
+ long num_iterations;
+ std::string xmlpath;
+ std::vector<std::string> extra_benchmarks;
+} bench_opts_t;
+
// This function returns a pointer less than 2 * alignment + or_mask bytes into the array.
-char *GetAlignedMemory(char *orig_ptr, size_t alignment, size_t or_mask);
+char* GetAlignedMemory(char* orig_ptr, size_t alignment, size_t or_mask);
-char *GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes);
+char* GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes);
-char *GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte);
+wchar_t* GetAlignedPtr(std::vector<wchar_t>* buf, size_t alignment, size_t nbytes);
-bool LockToCPU(int cpu_to_lock);
+char* GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte);
+
+bool LockToCPU(long cpu_to_lock);
#endif // _BIONIC_BENCHMARKS_UTIL_H
diff --git a/libc/Android.bp b/libc/Android.bp
index 845945a..204ad19 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -13,6 +13,7 @@
"bionic/sigblock.c",
"bionic/siginterrupt.c",
"bionic/sigsetmask.c",
+ "stdio/fmemopen.cpp",
"stdio/fread.c",
"stdio/parsefloat.c",
"stdio/refill.c",
@@ -41,6 +42,7 @@
"-Wextra",
"-Wunused",
"-Wno-deprecated-declarations",
+ "-Wno-gcc-compat",
"-Wframe-larger-than=2048",
// Try to catch typical 32-bit assumptions that break with 64-bit pointers.
@@ -237,9 +239,11 @@
"upstream-freebsd/lib/libc/string/wcspbrk.c",
"upstream-freebsd/lib/libc/string/wcsrchr.c",
"upstream-freebsd/lib/libc/string/wcsspn.c",
+ "upstream-freebsd/lib/libc/string/wcsstr.c",
"upstream-freebsd/lib/libc/string/wcstok.c",
"upstream-freebsd/lib/libc/string/wmemchr.c",
"upstream-freebsd/lib/libc/string/wmemcmp.c",
+ "upstream-freebsd/lib/libc/string/wmemcpy.c",
"upstream-freebsd/lib/libc/string/wmemmove.c",
"upstream-freebsd/lib/libc/string/wmemset.c",
],
@@ -385,7 +389,6 @@
name: "libc_openbsd_ndk",
defaults: ["libc_defaults"],
srcs: [
- "upstream-openbsd/lib/libc/compat-43/killpg.c",
"upstream-openbsd/lib/libc/gen/alarm.c",
"upstream-openbsd/lib/libc/gen/ctype_.c",
"upstream-openbsd/lib/libc/gen/daemon.c",
@@ -438,7 +441,6 @@
"upstream-openbsd/lib/libc/stdio/fgetwc.c",
"upstream-openbsd/lib/libc/stdio/fgetws.c",
"upstream-openbsd/lib/libc/stdio/flags.c",
- "upstream-openbsd/lib/libc/stdio/fmemopen.c",
"upstream-openbsd/lib/libc/stdio/fpurge.c",
"upstream-openbsd/lib/libc/stdio/fputs.c",
"upstream-openbsd/lib/libc/stdio/fputwc.c",
@@ -501,9 +503,7 @@
"upstream-openbsd/lib/libc/string/strspn.c",
"upstream-openbsd/lib/libc/string/strstr.c",
"upstream-openbsd/lib/libc/string/strtok.c",
- "upstream-openbsd/lib/libc/string/wmemcpy.c",
"upstream-openbsd/lib/libc/string/wcslcpy.c",
- "upstream-openbsd/lib/libc/string/wcsstr.c",
"upstream-openbsd/lib/libc/string/wcswidth.c",
],
@@ -776,6 +776,106 @@
}
// ========================================================
+// libc_fortify.a - container for our FORITFY
+// implementation details
+// ========================================================
+cc_library_static {
+ defaults: ["libc_defaults"],
+ srcs: ["bionic/fortify.cpp"],
+
+ name: "libc_fortify",
+
+ // Disable FORTIFY for the compilation of these, so we don't end up having
+ // FORTIFY silently call itself.
+ cflags: ["-U_FORTIFY_SOURCE", "-D__BIONIC_DECLARE_FORTIFY_HELPERS"],
+
+ arch: {
+ arm: {
+ cflags: ["-DNO___MEMCPY_CHK"],
+ srcs: [
+ "arch-arm/generic/bionic/__memcpy_chk.S",
+ ],
+ cortex_a7: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/cortex-a7/bionic/__strcat_chk.S",
+ "arch-arm/cortex-a7/bionic/__strcpy_chk.S",
+ ],
+ },
+ cortex_a53: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/cortex-a53/bionic/__strcat_chk.S",
+ "arch-arm/cortex-a53/bionic/__strcpy_chk.S",
+ ],
+ },
+ cortex_a53_a57: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/cortex-a15/bionic/__strcat_chk.S",
+ "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
+ ],
+ },
+ cortex_a8: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/cortex-a15/bionic/__strcat_chk.S",
+ "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
+ ],
+ },
+ cortex_a9: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/cortex-a9/bionic/__strcat_chk.S",
+ "arch-arm/cortex-a9/bionic/__strcpy_chk.S",
+ ],
+ },
+ cortex_a15: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/cortex-a15/bionic/__strcat_chk.S",
+ "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
+ ],
+ },
+ cortex_a73: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/denver/bionic/__strcat_chk.S",
+ "arch-arm/denver/bionic/__strcpy_chk.S",
+ ],
+ },
+ denver: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/denver/bionic/__strcat_chk.S",
+ "arch-arm/denver/bionic/__strcpy_chk.S",
+ ],
+ },
+ krait: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/krait/bionic/__strcat_chk.S",
+ "arch-arm/krait/bionic/__strcpy_chk.S",
+ ],
+ },
+ kryo: {
+ cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+ srcs: [
+ "arch-arm/krait/bionic/__strcat_chk.S",
+ "arch-arm/krait/bionic/__strcpy_chk.S",
+ ],
+ },
+ },
+ arm64: {
+ cflags: ["-DNO___MEMCPY_CHK"],
+ srcs: [
+ "arch-arm64/generic/bionic/__memcpy_chk.S",
+ ],
+ },
+ },
+}
+
+// ========================================================
// libc_bionic.a - home-grown C library code
// ========================================================
@@ -804,9 +904,6 @@
// debuggerd will look for the abort message in libc.so's copy.
"bionic/android_set_abort_message.cpp",
- "bionic/__memcpy_chk.cpp",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
"bionic/strchr.cpp",
"bionic/strnlen.c",
"bionic/strrchr.cpp",
@@ -832,15 +929,10 @@
"arch-arm/bionic/syscall.S",
"arch-arm/bionic/vfork.S",
],
- exclude_srcs: [
- "bionic/__memcpy_chk.cpp",
- ],
cortex_a7: {
srcs: [
"arch-arm/cortex-a7/bionic/memset.S",
"arch-arm/cortex-a7/bionic/memcpy.S",
- "arch-arm/cortex-a7/bionic/__strcat_chk.S",
- "arch-arm/cortex-a7/bionic/__strcpy_chk.S",
"arch-arm/cortex-a15/bionic/stpcpy.S",
"arch-arm/cortex-a15/bionic/strcat.S",
@@ -856,15 +948,11 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
cortex_a53: {
srcs: [
"arch-arm/cortex-a53/bionic/memcpy.S",
- "arch-arm/cortex-a53/bionic/__strcat_chk.S",
- "arch-arm/cortex-a53/bionic/__strcpy_chk.S",
"arch-arm/cortex-a7/bionic/memset.S",
@@ -882,8 +970,6 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
cortex_a53_a57: {
@@ -892,10 +978,8 @@
"arch-arm/cortex-a15/bionic/memset.S",
"arch-arm/cortex-a15/bionic/stpcpy.S",
"arch-arm/cortex-a15/bionic/strcat.S",
- "arch-arm/cortex-a15/bionic/__strcat_chk.S",
"arch-arm/cortex-a15/bionic/strcmp.S",
"arch-arm/cortex-a15/bionic/strcpy.S",
- "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
"arch-arm/cortex-a15/bionic/strlen.S",
"arch-arm/denver/bionic/memmove.S",
@@ -906,8 +990,6 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
cortex_a8: {
@@ -916,10 +998,8 @@
"arch-arm/cortex-a15/bionic/memset.S",
"arch-arm/cortex-a15/bionic/stpcpy.S",
"arch-arm/cortex-a15/bionic/strcat.S",
- "arch-arm/cortex-a15/bionic/__strcat_chk.S",
"arch-arm/cortex-a15/bionic/strcmp.S",
"arch-arm/cortex-a15/bionic/strcpy.S",
- "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
"arch-arm/cortex-a15/bionic/strlen.S",
"arch-arm/denver/bionic/memmove.S",
@@ -930,8 +1010,6 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
cortex_a9: {
@@ -940,10 +1018,8 @@
"arch-arm/cortex-a9/bionic/memset.S",
"arch-arm/cortex-a9/bionic/stpcpy.S",
"arch-arm/cortex-a9/bionic/strcat.S",
- "arch-arm/cortex-a9/bionic/__strcat_chk.S",
"arch-arm/cortex-a9/bionic/strcmp.S",
"arch-arm/cortex-a9/bionic/strcpy.S",
- "arch-arm/cortex-a9/bionic/__strcpy_chk.S",
"arch-arm/cortex-a9/bionic/strlen.S",
"arch-arm/denver/bionic/memmove.S",
@@ -954,8 +1030,6 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
cortex_a15: {
@@ -964,10 +1038,8 @@
"arch-arm/cortex-a15/bionic/memset.S",
"arch-arm/cortex-a15/bionic/stpcpy.S",
"arch-arm/cortex-a15/bionic/strcat.S",
- "arch-arm/cortex-a15/bionic/__strcat_chk.S",
"arch-arm/cortex-a15/bionic/strcmp.S",
"arch-arm/cortex-a15/bionic/strcpy.S",
- "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
"arch-arm/cortex-a15/bionic/strlen.S",
"arch-arm/denver/bionic/memmove.S",
@@ -978,8 +1050,6 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
cortex_a73: {
@@ -988,8 +1058,6 @@
"arch-arm/denver/bionic/memcpy.S",
"arch-arm/denver/bionic/memmove.S",
- "arch-arm/denver/bionic/__strcat_chk.S",
- "arch-arm/denver/bionic/__strcpy_chk.S",
"arch-arm/krait/bionic/strcmp.S",
@@ -1004,8 +1072,6 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
denver: {
@@ -1013,8 +1079,6 @@
"arch-arm/denver/bionic/memcpy.S",
"arch-arm/denver/bionic/memmove.S",
"arch-arm/denver/bionic/memset.S",
- "arch-arm/denver/bionic/__strcat_chk.S",
- "arch-arm/denver/bionic/__strcpy_chk.S",
// Use cortex-a15 versions of strcat/strcpy/strlen.
"arch-arm/cortex-a15/bionic/stpcpy.S",
@@ -1029,8 +1093,6 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
krait: {
@@ -1038,8 +1100,6 @@
"arch-arm/krait/bionic/memcpy.S",
"arch-arm/krait/bionic/memset.S",
"arch-arm/krait/bionic/strcmp.S",
- "arch-arm/krait/bionic/__strcat_chk.S",
- "arch-arm/krait/bionic/__strcpy_chk.S",
// Use cortex-a15 versions of strcat/strcpy/strlen.
"arch-arm/cortex-a15/bionic/stpcpy.S",
@@ -1055,8 +1115,6 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
kryo: {
@@ -1064,8 +1122,6 @@
"arch-arm/kryo/bionic/memcpy.S",
"arch-arm/cortex-a7/bionic/memset.S",
"arch-arm/krait/bionic/strcmp.S",
- "arch-arm/krait/bionic/__strcat_chk.S",
- "arch-arm/krait/bionic/__strcpy_chk.S",
// Use cortex-a15 versions of strcat/strcpy/strlen.
"arch-arm/cortex-a15/bionic/stpcpy.S",
@@ -1081,8 +1137,6 @@
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
- "bionic/__strcat_chk.cpp",
- "bionic/__strcpy_chk.cpp",
],
},
},
@@ -1331,6 +1385,7 @@
defaults: ["libc_defaults"],
srcs: [
"bionic/NetdClientDispatch.cpp",
+ "bionic/__bionic_get_shell_path.cpp",
"bionic/__cmsg_nxthdr.cpp",
"bionic/__errno.cpp",
"bionic/__gnu_basename.cpp",
@@ -1345,6 +1400,7 @@
"bionic/assert.cpp",
"bionic/atof.cpp",
"bionic/bionic_arc4random.cpp",
+ "bionic/bionic_futex.cpp",
"bionic/bionic_netlink.cpp",
"bionic/bionic_systrace.cpp",
"bionic/bionic_time_conversions.cpp",
@@ -1378,7 +1434,6 @@
"bionic/fgetxattr.cpp",
"bionic/flistxattr.cpp",
"bionic/flockfile.cpp",
- "bionic/fortify.cpp",
"bionic/fpclassify.cpp",
"bionic/fsetxattr.cpp",
"bionic/ftruncate.cpp",
@@ -1393,9 +1448,12 @@
"bionic/getpriority.cpp",
"bionic/gettid.cpp",
"bionic/grp_pwd.cpp",
+ "bionic/iconv.cpp",
+ "bionic/icu_wrappers.cpp",
"bionic/ifaddrs.cpp",
"bionic/inotify_init.cpp",
"bionic/ioctl.cpp",
+ "bionic/killpg.cpp",
"bionic/langinfo.cpp",
"bionic/lchown.cpp",
"bionic/lfs64_support.cpp",
@@ -1409,7 +1467,6 @@
"bionic/mblen.cpp",
"bionic/mbrtoc16.cpp",
"bionic/mbrtoc32.cpp",
- "bionic/mbstate.cpp",
"bionic/memmem.cpp",
"bionic/mempcpy.cpp",
"bionic/mkdir.cpp",
@@ -1500,6 +1557,7 @@
"bionic/wchar_l.cpp",
"bionic/wcstod.cpp",
"bionic/wctype.cpp",
+ "bionic/wcwidth.cpp",
"bionic/wmempcpy.cpp",
],
@@ -1645,6 +1703,7 @@
whole_static_libs: [
"libc_bionic_ndk",
+ "libc_fortify",
"libc_freebsd",
"libc_freebsd_large_stack",
"libc_gdtoa",
@@ -1679,6 +1738,7 @@
"libc_bionic",
"libc_bionic_ndk",
"libc_dns",
+ "libc_fortify",
"libc_freebsd",
"libc_freebsd_large_stack",
"libc_gdtoa",
@@ -1893,6 +1953,8 @@
no_default_compiler_flags: true,
+ cflags: ["-Wno-gcc-compat", "-Werror"],
+
arch: {
arm: {
local_include_dirs: ["arch-arm/include"],
@@ -1913,12 +1975,14 @@
local_include_dirs: ["arch-x86_64/include"],
},
},
- clang: false,
+ clang: true,
}
cc_defaults {
name: "crt_so_defaults",
+ cflags: ["-Wno-gcc-compat", "-Werror"],
+
vendor_available: true,
arch: {
mips: {
diff --git a/libc/NOTICE b/libc/NOTICE
index bcc9691..90de7ef 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -682,6 +682,31 @@
-------------------------------------------------------------------
+Copyright (C) 2013 Pietro Cerutti <gahr@FreeBSD.org>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -862,22 +887,6 @@
http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--------------------------------------------------------------------
-
-Copyright (C) 2015 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -5087,23 +5096,6 @@
-------------------------------------------------------------------
-Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
-Copyright (c) 2009 Ted Unangst
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
--------------------------------------------------------------------
-
Copyright (c) 2011 The Android Open Source Project
Copyright (c) 2008 ARM Ltd
All rights reserved.
@@ -5403,32 +5395,6 @@
-------------------------------------------------------------------
-Copyright (c) 2013 David Chisnall
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
Copyright (c) 2013 The NetBSD Foundation, Inc.
All rights reserved.
diff --git a/libc/SECCOMP_WHITELIST.TXT b/libc/SECCOMP_WHITELIST.TXT
index 473cb41..2c4767b 100644
--- a/libc/SECCOMP_WHITELIST.TXT
+++ b/libc/SECCOMP_WHITELIST.TXT
@@ -46,9 +46,6 @@
# Needed for strace
int tkill:tkill(int tid, int sig) all
-# b/35034743
-int syncfs:syncfs(int fd) all
-
# b/34763393
int seccomp:seccomp(unsigned int operation, unsigned int flags, void *args) all
@@ -63,7 +60,7 @@
# b/34651972
int access:access(const char *pathname, int mode) arm,x86,mips
-int stat64:stat64(const char *restrict path, struct stat64 *restrict buf) arm,x86,mips
+int stat64:stat64(const char*, struct stat64*) arm,x86,mips
# b/34813887
int open:open(const char *path, int oflag, ... ) arm,x86,mips
@@ -88,7 +85,7 @@
int unlink:unlink(const char *pathname) arm,x86,mips
# b/35059702
-int lstat64:lstat64(const char *restrict path, struct stat64 *restrict buf) arm,x86,mips
+int lstat64:lstat64(const char*, struct stat64*) arm,x86,mips
# b/35217603
int fcntl:fcntl(int fd, int cmd, ... /* arg */ ) arm,x86,mips
diff --git a/libc/SECCOMP_WHITELIST_GLOBAL.TXT b/libc/SECCOMP_WHITELIST_GLOBAL.TXT
new file mode 100644
index 0000000..f3e5a98
--- /dev/null
+++ b/libc/SECCOMP_WHITELIST_GLOBAL.TXT
@@ -0,0 +1,18 @@
+# This file is used to populate seccomp's global whitelist policy in
+# combination with SYSCALLS.TXT, SECCOMP_BLACKLIST.TXT and
+# SECCOMP_WHITELIST.TXT. Unlike the policy used in normal operation this
+# policy is applied globally during the early stage of init, if global seccomp
+# is enabled.
+#
+# See the description at the top of SYSCALLS.TXT for an explanation of the
+# format of the entries in this file.
+#
+# This file is processed by a python script named genseccomp.py.
+
+# syscalls needed to boot android
+int swapon(const char*, int) all
+long keyctl(int, ...) all
+key_serial_t add_key(const char*, const char*, const void*, size_t, key_serial_t) all
+
+# b/62715671
+int finit_module(int, const char*, int) all
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index d674630..a1d1af0 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -131,6 +131,7 @@
int fchown:fchown32(int, uid_t, gid_t) arm,x86
int fchown:fchown(int, uid_t, gid_t) arm64,mips,mips64,x86_64
void sync(void) all
+int syncfs(int) all
int ___fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all
ssize_t ___fgetxattr:fgetxattr(int, const char*, void*, size_t) all
ssize_t ___flistxattr:flistxattr(int, char*, size_t) all
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy.S b/libc/arch-arm/cortex-a15/bionic/memcpy.S
index 7ad0093..4297cd6 100644
--- a/libc/arch-arm/cortex-a15/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a15/bionic/memcpy.S
@@ -63,17 +63,6 @@
// arch. The code generated is exactly the same.
.arch armv7-a
-ENTRY(__memcpy_chk)
- cmp r2, r3
- bls memcpy
-
- // Preserve lr for backtrace.
- push {lr}
- .cfi_def_cfa_offset 4
- .cfi_rel_offset lr, 0
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
// Prototype: void *memcpy (void *dst, const void *src, size_t count).
ENTRY(memcpy)
pld [r1, #64]
diff --git a/libc/arch-arm/cortex-a53/bionic/memcpy.S b/libc/arch-arm/cortex-a53/bionic/memcpy.S
index 7ad0093..4297cd6 100644
--- a/libc/arch-arm/cortex-a53/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a53/bionic/memcpy.S
@@ -63,17 +63,6 @@
// arch. The code generated is exactly the same.
.arch armv7-a
-ENTRY(__memcpy_chk)
- cmp r2, r3
- bls memcpy
-
- // Preserve lr for backtrace.
- push {lr}
- .cfi_def_cfa_offset 4
- .cfi_rel_offset lr, 0
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
// Prototype: void *memcpy (void *dst, const void *src, size_t count).
ENTRY(memcpy)
pld [r1, #64]
diff --git a/libc/arch-arm/cortex-a7/bionic/memcpy.S b/libc/arch-arm/cortex-a7/bionic/memcpy.S
index 7ad0093..4297cd6 100644
--- a/libc/arch-arm/cortex-a7/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a7/bionic/memcpy.S
@@ -63,17 +63,6 @@
// arch. The code generated is exactly the same.
.arch armv7-a
-ENTRY(__memcpy_chk)
- cmp r2, r3
- bls memcpy
-
- // Preserve lr for backtrace.
- push {lr}
- .cfi_def_cfa_offset 4
- .cfi_rel_offset lr, 0
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
// Prototype: void *memcpy (void *dst, const void *src, size_t count).
ENTRY(memcpy)
pld [r1, #64]
diff --git a/libc/arch-arm/cortex-a9/bionic/memcpy.S b/libc/arch-arm/cortex-a9/bionic/memcpy.S
index 93a8629..5a986d1 100644
--- a/libc/arch-arm/cortex-a9/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a9/bionic/memcpy.S
@@ -39,18 +39,6 @@
.thumb
.thumb_func
-ENTRY(__memcpy_chk)
- cmp r2, r3
- bls memcpy
-
- // Preserve lr for backtrace.
- push {lr}
- .cfi_def_cfa_offset 4
- .cfi_rel_offset lr, 0
-
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
ENTRY(memcpy)
pld [r1, #0]
stmfd sp!, {r0, lr}
diff --git a/libc/arch-arm/denver/bionic/memcpy.S b/libc/arch-arm/denver/bionic/memcpy.S
index 743c74b..8528f28 100644
--- a/libc/arch-arm/denver/bionic/memcpy.S
+++ b/libc/arch-arm/denver/bionic/memcpy.S
@@ -65,18 +65,6 @@
// arch. The code generated is exactly the same.
.arch armv7-a
-ENTRY(__memcpy_chk)
- cmp r2, r3
- bls memcpy
-
- // Preserve lr for backtrace.
- push {lr}
- .cfi_def_cfa_offset 4
- .cfi_rel_offset lr, 0
-
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
ENTRY(memcpy)
pld [r1, #64]
push {r0, lr}
diff --git a/libc/bionic/__memcpy_chk.cpp b/libc/arch-arm/generic/bionic/__memcpy_chk.S
similarity index 74%
rename from libc/bionic/__memcpy_chk.cpp
rename to libc/arch-arm/generic/bionic/__memcpy_chk.S
index 7b42d99..7ee2a8f 100644
--- a/libc/bionic/__memcpy_chk.cpp
+++ b/libc/arch-arm/generic/bionic/__memcpy_chk.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,15 +26,18 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
+#include <private/bionic_asm.h>
-#include <string.h>
+ .syntax unified
-#include "private/bionic_fortify.h"
+ENTRY(__memcpy_chk)
+ cmp r2, r3
+ bls memcpy
-// Runtime implementation of __memcpy_chk (used directly by compiler, not in headers).
-extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
- __check_count("memcpy", "count", count);
- __check_buffer_access("memcpy", "write into", count, dst_len);
- return memcpy(dst, src, count);
-}
+ // Preserve lr for backtrace.
+ push {lr}
+ .cfi_def_cfa_offset 4
+ .cfi_rel_offset lr, 0
+
+ bl __memcpy_chk_fail
+END(__memcpy_chk)
diff --git a/libc/arch-arm/generic/bionic/memcpy.S b/libc/arch-arm/generic/bionic/memcpy.S
index a3ebb95..d1e4372 100644
--- a/libc/arch-arm/generic/bionic/memcpy.S
+++ b/libc/arch-arm/generic/bionic/memcpy.S
@@ -37,18 +37,6 @@
.syntax unified
-ENTRY(__memcpy_chk)
- cmp r2, r3
- bls memcpy
-
- // Preserve lr for backtrace.
- push {lr}
- .cfi_def_cfa_offset 4
- .cfi_rel_offset lr, 0
-
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
ENTRY(memcpy)
/* The stack must always be 64-bits aligned to be compliant with the
* ARM ABI. Since we have to save R0, we might as well save R4
diff --git a/libc/arch-arm/generic/bionic/strlen.c b/libc/arch-arm/generic/bionic/strlen.c
index f6b9209..dccd564 100644
--- a/libc/arch-arm/generic/bionic/strlen.c
+++ b/libc/arch-arm/generic/bionic/strlen.c
@@ -67,53 +67,46 @@
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
+ "bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
#if !defined(__OPTIMIZE_SIZE__)
- "bne 1f \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
+ "bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
#endif
- "beq 0b \n"
+ "b 0b \n"
"1: \n"
"add %[l], %[l], %[s] \n"
"tst %[v], #0xFF \n"
diff --git a/libc/arch-arm/krait/bionic/memcpy.S b/libc/arch-arm/krait/bionic/memcpy.S
index de6f432..f22c063 100644
--- a/libc/arch-arm/krait/bionic/memcpy.S
+++ b/libc/arch-arm/krait/bionic/memcpy.S
@@ -42,18 +42,6 @@
.thumb
.thumb_func
-ENTRY(__memcpy_chk)
- cmp r2, r3
- bls memcpy
-
- // Preserve lr for backtrace.
- push {lr}
- .cfi_def_cfa_offset 4
- .cfi_rel_offset lr, 0
-
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
ENTRY(memcpy)
pld [r1, #64]
stmfd sp!, {r0, lr}
diff --git a/libc/arch-arm/kryo/bionic/memcpy.S b/libc/arch-arm/kryo/bionic/memcpy.S
index 7e96f7d..e9ee2ac 100644
--- a/libc/arch-arm/kryo/bionic/memcpy.S
+++ b/libc/arch-arm/kryo/bionic/memcpy.S
@@ -34,18 +34,6 @@
#define PLDSIZE (128) /* L2 cache line size */
.code 32
-ENTRY(__memcpy_chk)
- cmp r2, r3
- bls memcpy
-
- // Preserve lr for backtrace.
- push {lr}
- .cfi_def_cfa_offset 4
- .cfi_rel_offset lr, 0
-
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
ENTRY(memcpy)
push {r0}
.cfi_def_cfa_offset 4
diff --git a/libc/arch-arm/syscalls/syncfs.S b/libc/arch-arm/syscalls/syncfs.S
new file mode 100644
index 0000000..26f2f14
--- /dev/null
+++ b/libc/arch-arm/syscalls/syncfs.S
@@ -0,0 +1,16 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(syncfs)
+ mov ip, r7
+ .cfi_register r7, ip
+ ldr r7, =__NR_syncfs
+ swi #0
+ mov r7, ip
+ .cfi_restore r7
+ cmn r0, #(MAX_ERRNO + 1)
+ bxls lr
+ neg r0, r0
+ b __set_errno_internal
+END(syncfs)
diff --git a/libc/arch-arm64/denver64/bionic/memcpy.S b/libc/arch-arm64/denver64/bionic/memcpy.S
index 0be2aac..fc487d3 100644
--- a/libc/arch-arm64/denver64/bionic/memcpy.S
+++ b/libc/arch-arm64/denver64/bionic/memcpy.S
@@ -30,19 +30,6 @@
#include <private/bionic_asm.h>
-ENTRY(__memcpy_chk)
- cmp x2, x3
- bls memcpy
-
- // Preserve for accurate backtrace.
- stp x29, x30, [sp, -16]!
- .cfi_def_cfa_offset 16
- .cfi_rel_offset x29, 0
- .cfi_rel_offset x30, 8
-
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
ENTRY(memcpy)
#include "memcpy_base.S"
END(memcpy)
diff --git a/libc/bionic/__memcpy_chk.cpp b/libc/arch-arm64/generic/bionic/__memcpy_chk.S
similarity index 74%
copy from libc/bionic/__memcpy_chk.cpp
copy to libc/arch-arm64/generic/bionic/__memcpy_chk.S
index 7b42d99..4217775 100644
--- a/libc/bionic/__memcpy_chk.cpp
+++ b/libc/arch-arm64/generic/bionic/__memcpy_chk.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,15 +26,17 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
+#include <private/bionic_asm.h>
-#include <string.h>
+ENTRY(__memcpy_chk)
+ cmp x2, x3
+ bls memcpy
-#include "private/bionic_fortify.h"
+ // Preserve for accurate backtrace.
+ stp x29, x30, [sp, -16]!
+ .cfi_def_cfa_offset 16
+ .cfi_rel_offset x29, 0
+ .cfi_rel_offset x30, 8
-// Runtime implementation of __memcpy_chk (used directly by compiler, not in headers).
-extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
- __check_count("memcpy", "count", count);
- __check_buffer_access("memcpy", "write into", count, dst_len);
- return memcpy(dst, src, count);
-}
+ bl __memcpy_chk_fail
+END(__memcpy_chk)
diff --git a/libc/arch-arm64/generic/bionic/memcpy.S b/libc/arch-arm64/generic/bionic/memcpy.S
index 0be2aac..fc487d3 100644
--- a/libc/arch-arm64/generic/bionic/memcpy.S
+++ b/libc/arch-arm64/generic/bionic/memcpy.S
@@ -30,19 +30,6 @@
#include <private/bionic_asm.h>
-ENTRY(__memcpy_chk)
- cmp x2, x3
- bls memcpy
-
- // Preserve for accurate backtrace.
- stp x29, x30, [sp, -16]!
- .cfi_def_cfa_offset 16
- .cfi_rel_offset x29, 0
- .cfi_rel_offset x30, 8
-
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
ENTRY(memcpy)
#include "memcpy_base.S"
END(memcpy)
diff --git a/libc/arch-arm64/syscalls/syncfs.S b/libc/arch-arm64/syscalls/syncfs.S
new file mode 100644
index 0000000..773c0cb
--- /dev/null
+++ b/libc/arch-arm64/syscalls/syncfs.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(syncfs)
+ mov x8, __NR_syncfs
+ svc #0
+
+ cmn x0, #(MAX_ERRNO + 1)
+ cneg x0, x0, hi
+ b.hi __set_errno_internal
+
+ ret
+END(syncfs)
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index d3a0f07..45c9ea7 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -30,16 +30,13 @@
#include <stddef.h>
#include <stdint.h>
-__attribute__((__section__(".preinit_array")))
-void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
+#define SECTION(name) __attribute__((__section__(name)))
+SECTION(".preinit_array") void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
+SECTION(".init_array") void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
+SECTION(".fini_array") void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
+#undef SECTION
-__attribute__((__section__(".init_array")))
-void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
-
-__attribute__((__section__(".fini_array")))
-void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
-
-static void _start_main(void* raw_args) {
+static void _start_main(void* raw_args) __used {
structors_array_t array;
array.preinit_array = &__PREINIT_ARRAY__;
array.init_array = &__INIT_ARRAY__;
diff --git a/libc/arch-mips/syscalls/syncfs.S b/libc/arch-mips/syscalls/syncfs.S
new file mode 100644
index 0000000..cd87a61
--- /dev/null
+++ b/libc/arch-mips/syscalls/syncfs.S
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(syncfs)
+ .set noreorder
+ .cpload t9
+ li v0, __NR_syncfs
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ la t9,__set_errno_internal
+ j t9
+ nop
+ .set reorder
+END(syncfs)
diff --git a/libc/arch-mips64/syscalls/syncfs.S b/libc/arch-mips64/syscalls/syncfs.S
new file mode 100644
index 0000000..504ca4a
--- /dev/null
+++ b/libc/arch-mips64/syscalls/syncfs.S
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(syncfs)
+ .set push
+ .set noreorder
+ li v0, __NR_syncfs
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ move t0, ra
+ bal 2f
+ nop
+2:
+ .cpsetup ra, t1, 2b
+ LA t9,__set_errno_internal
+ .cpreturn
+ j t9
+ move ra, t0
+ .set pop
+END(syncfs)
diff --git a/libc/arch-x86/syscalls/syncfs.S b/libc/arch-x86/syscalls/syncfs.S
new file mode 100644
index 0000000..c08688a
--- /dev/null
+++ b/libc/arch-x86/syscalls/syncfs.S
@@ -0,0 +1,29 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(syncfs)
+ pushl %ebx
+ .cfi_def_cfa_offset 8
+ .cfi_rel_offset ebx, 0
+
+ call __kernel_syscall
+ pushl %eax
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset eax, 0
+
+ mov 12(%esp), %ebx
+ movl $__NR_syncfs, %eax
+ call *(%esp)
+ addl $4, %esp
+
+ cmpl $-MAX_ERRNO, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno_internal
+ addl $4, %esp
+1:
+ popl %ebx
+ ret
+END(syncfs)
diff --git a/libc/arch-x86_64/syscalls/syncfs.S b/libc/arch-x86_64/syscalls/syncfs.S
new file mode 100644
index 0000000..12dee08
--- /dev/null
+++ b/libc/arch-x86_64/syscalls/syncfs.S
@@ -0,0 +1,15 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(syncfs)
+ movl $__NR_syncfs, %eax
+ syscall
+ cmpq $-MAX_ERRNO, %rax
+ jb 1f
+ negl %eax
+ movl %eax, %edi
+ call __set_errno_internal
+1:
+ ret
+END(syncfs)
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 99ff0c7..d81ef34 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -60,43 +60,36 @@
struct BufferOutputStream {
public:
- BufferOutputStream(char* buffer, size_t size) : total(0) {
- buffer_ = buffer;
- end_ = buffer + size - 1;
- pos_ = buffer_;
- pos_[0] = '\0';
+ BufferOutputStream(char* buffer, size_t size) : total(0), pos_(buffer), avail_(size) {
+ if (avail_ > 0) pos_[0] = '\0';
}
-
- ~BufferOutputStream() {}
+ ~BufferOutputStream() = default;
void Send(const char* data, int len) {
if (len < 0) {
len = strlen(data);
}
-
total += len;
- while (len > 0) {
- int avail = end_ - pos_;
- if (avail == 0) {
- return;
- }
- if (avail > len) {
- avail = len;
- }
- memcpy(pos_, data, avail);
- pos_ += avail;
- pos_[0] = '\0';
- len -= avail;
+ if (avail_ <= 1) {
+ // No space to put anything else.
+ return;
}
+
+ if (static_cast<size_t>(len) >= avail_) {
+ len = avail_ - 1;
+ }
+ memcpy(pos_, data, len);
+ pos_ += len;
+ pos_[0] = '\0';
+ avail_ -= len;
}
size_t total;
private:
- char* buffer_;
char* pos_;
- char* end_;
+ size_t avail_;
};
struct FdOutputStream {
@@ -107,16 +100,15 @@
if (len < 0) {
len = strlen(data);
}
-
total += len;
while (len > 0) {
- int rc = TEMP_FAILURE_RETRY(write(fd_, data, len));
- if (rc == -1) {
+ ssize_t bytes = TEMP_FAILURE_RETRY(write(fd_, data, len));
+ if (bytes == -1) {
return;
}
- data += rc;
- len -= rc;
+ data += bytes;
+ len -= bytes;
}
}
@@ -409,15 +401,6 @@
}
}
-int async_safe_format_buffer(char* buffer, size_t buffer_size, const char* format, ...) {
- BufferOutputStream os(buffer, buffer_size);
- va_list args;
- va_start(args, format);
- out_vformat(os, format, args);
- va_end(args);
- return os.total;
-}
-
int async_safe_format_buffer_va_list(char* buffer, size_t buffer_size, const char* format,
va_list args) {
BufferOutputStream os(buffer, buffer_size);
@@ -425,6 +408,14 @@
return os.total;
}
+int async_safe_format_buffer(char* buffer, size_t buffer_size, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ int buffer_len = async_safe_format_buffer_va_list(buffer, buffer_size, format, args);
+ va_end(args);
+ return buffer_len;
+}
+
int async_safe_format_fd(int fd, const char* format, ...) {
FdOutputStream os(fd);
va_list args;
diff --git a/libc/async_safe/include/async_safe/log.h b/libc/async_safe/include/async_safe/log.h
index 6fdb84f..2f54742 100644
--- a/libc/async_safe/include/async_safe/log.h
+++ b/libc/async_safe/include/async_safe/log.h
@@ -78,14 +78,8 @@
// These functions do return, so callers that want to abort, must do so themselves,
// or use the macro above.
-void async_safe_fatal_no_abort(const char* _Nonnull fmt, ...) __printflike(1, 2);
-#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
-void async_safe_fatal_va_list(
- const char* _Nullable prefix, const char* _Nonnull fmt, va_list);
-#else // defined(__mips__) || defined(__i386__)
-void async_safe_fatal_va_list(
- const char* _Nullable prefix, const char* _Nonnull fmt, va_list _Nonnull);
-#endif
+void async_safe_fatal_no_abort(const char* fmt, ...) __printflike(1, 2);
+void async_safe_fatal_va_list(const char* prefix, const char* fmt, va_list args);
//
// Formatting routines for the C library's internal debugging.
@@ -93,26 +87,13 @@
// These are async signal safe, so they can be called from signal handlers.
//
-int async_safe_format_buffer(char* _Nonnull buf, size_t size, const char* _Nonnull fmt, ...) __printflike(3, 4);
+int async_safe_format_buffer(char* buf, size_t size, const char* fmt, ...) __printflike(3, 4);
+int async_safe_format_buffer_va_list(char* buffer, size_t buffer_size, const char* format, va_list args);
-#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
-int async_safe_format_buffer_va_list(
- char* _Nonnull buffer, size_t buffer_size, const char* _Nonnull format, va_list args);
-#else // defined(__mips__) || defined(__i386__)
-int async_safe_format_buffer_va_list(
- char* _Nonnull buffer, size_t buffer_size, const char* _Nonnull format, va_list _Nonnull args);
-#endif
-
-int async_safe_format_fd(int fd, const char* _Nonnull format , ...) __printflike(2, 3);
-int async_safe_format_log(int pri, const char* _Nonnull tag, const char* _Nonnull fmt, ...) __printflike(3, 4);
-#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
-int async_safe_format_log_va_list(
- int pri, const char* _Nonnull tag, const char* _Nonnull fmt, va_list ap);
-#else // defined(__mips__) || defined(__i386__)
-int async_safe_format_log_va_list(
- int pri, const char* _Nonnull tag, const char* _Nonnull fmt, va_list _Nonnull ap);
-#endif
-int async_safe_write_log(int pri, const char* _Nonnull tag, const char* _Nonnull msg);
+int async_safe_format_fd(int fd, const char* format , ...) __printflike(2, 3);
+int async_safe_format_log(int pri, const char* tag, const char* fmt, ...) __printflike(3, 4);
+int async_safe_format_log_va_list( int pri, const char* tag, const char* fmt, va_list ap);
+int async_safe_write_log(int pri, const char* tag, const char* msg);
#define CHECK(predicate) \
do { \
diff --git a/libc/bionic/__strcat_chk.cpp b/libc/bionic/__bionic_get_shell_path.cpp
similarity index 66%
rename from libc/bionic/__strcat_chk.cpp
rename to libc/bionic/__bionic_get_shell_path.cpp
index 16b2327..477fa4a 100644
--- a/libc/bionic/__strcat_chk.cpp
+++ b/libc/bionic/__bionic_get_shell_path.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,25 +26,26 @@
* SUCH DAMAGE.
*/
+#include <errno.h>
#include <string.h>
+#include <sys/cdefs.h>
+#include <unistd.h>
-#include "private/bionic_fortify.h"
+__LIBC_HIDDEN__ static const char* __libc_system_sh = "/system/bin/sh";
+__LIBC_HIDDEN__ static const char* __libc_vendor_sh = "/vendor/bin/sh";
-// Runtime implementation of __builtin____strcat_chk (used directly by compiler, not in headers).
-extern "C" char* __strcat_chk(char* __restrict dst, const char* __restrict src,
- size_t dst_buf_size) {
- char* save = dst;
- size_t dst_len = __strlen_chk(dst, dst_buf_size);
-
- dst += dst_len;
- dst_buf_size -= dst_len;
-
- while ((*dst++ = *src++) != '\0') {
- dst_buf_size--;
- if (__predict_false(dst_buf_size == 0)) {
- __fortify_fatal("strcat: prevented write past end of %zu-byte buffer", dst_buf_size);
- }
+static const char* init_sh_path() {
+ /* look for /system or /vendor prefix */
+ char exe_path[7];
+ ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path));
+ if (len != -1 && !strncmp(exe_path, __libc_vendor_sh, sizeof(exe_path))) {
+ return __libc_vendor_sh;
}
- return save;
+ return __libc_system_sh;
+}
+
+__LIBC_HIDDEN__ extern "C" const char* __bionic_get_shell_path() {
+ static const char* sh_path = init_sh_path();
+ return sh_path;
}
diff --git a/libc/bionic/__cxa_guard.cpp b/libc/bionic/__cxa_guard.cpp
index 06926df..30b5f41 100644
--- a/libc/bionic/__cxa_guard.cpp
+++ b/libc/bionic/__cxa_guard.cpp
@@ -104,7 +104,7 @@
}
}
- __futex_wait_ex(&gv->state, false, CONSTRUCTION_UNDERWAY_WITH_WAITER, false, nullptr);
+ __futex_wait_ex(&gv->state, false, CONSTRUCTION_UNDERWAY_WITH_WAITER);
old_value = atomic_load_explicit(&gv->state, memory_order_acquire);
}
}
diff --git a/libc/bionic/assert.cpp b/libc/bionic/assert.cpp
index 41831cb..0f4ee97 100644
--- a/libc/bionic/assert.cpp
+++ b/libc/bionic/assert.cpp
@@ -39,7 +39,3 @@
void __assert2(const char* file, int line, const char* function, const char* failed_expression) {
async_safe_fatal("%s:%d: %s: assertion \"%s\" failed", file, line, function, failed_expression);
}
-
-extern "C" __LIBC_HIDDEN__ void longjmperror() {
- async_safe_fatal("longjmp botch");
-}
diff --git a/libc/bionic/bionic_futex.cpp b/libc/bionic/bionic_futex.cpp
new file mode 100644
index 0000000..dd66e40
--- /dev/null
+++ b/libc/bionic/bionic_futex.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "private/bionic_futex.h"
+
+#include <time.h>
+
+#include "private/bionic_time_conversions.h"
+
+int __futex_wait_ex(volatile void* ftx, bool shared, int value, bool use_realtime_clock,
+ const timespec* abs_timeout) {
+ const timespec* futex_abs_timeout = abs_timeout;
+ // pthread's and semaphore's default behavior is to use CLOCK_REALTIME, however this behavior is
+ // essentially never intended, as that clock is prone to change discontinuously.
+ //
+ // What users really intend is to use CLOCK_MONOTONIC, however only pthread_cond_timedwait()
+ // provides this as an option and even there, a large amount of existing code does not opt into
+ // CLOCK_MONOTONIC.
+ //
+ // We have seen numerous bugs directly attributable to this difference. Therefore, we provide
+ // this general workaround to always use CLOCK_MONOTONIC for waiting, regardless of what the input
+ // timespec is.
+ timespec converted_monotonic_abs_timeout;
+ if (abs_timeout && use_realtime_clock) {
+ monotonic_time_from_realtime_time(converted_monotonic_abs_timeout, *abs_timeout);
+ if (converted_monotonic_abs_timeout.tv_sec < 0) {
+ return -ETIMEDOUT;
+ }
+ futex_abs_timeout = &converted_monotonic_abs_timeout;
+ }
+
+ return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE), value,
+ futex_abs_timeout, FUTEX_BITSET_MATCH_ANY);
+}
diff --git a/libc/bionic/bionic_time_conversions.cpp b/libc/bionic/bionic_time_conversions.cpp
index ade3a55..d21e12e 100644
--- a/libc/bionic/bionic_time_conversions.cpp
+++ b/libc/bionic/bionic_time_conversions.cpp
@@ -51,3 +51,24 @@
tv.tv_sec = ts.tv_sec;
tv.tv_usec = ts.tv_nsec / 1000;
}
+
+void monotonic_time_from_realtime_time(timespec& monotonic_time, const timespec& realtime_time) {
+ monotonic_time = realtime_time;
+
+ timespec cur_monotonic_time;
+ clock_gettime(CLOCK_MONOTONIC, &cur_monotonic_time);
+ timespec cur_realtime_time;
+ clock_gettime(CLOCK_REALTIME, &cur_realtime_time);
+
+ monotonic_time.tv_nsec -= cur_realtime_time.tv_nsec;
+ monotonic_time.tv_nsec += cur_monotonic_time.tv_nsec;
+ if (monotonic_time.tv_nsec >= NS_PER_S) {
+ monotonic_time.tv_nsec -= NS_PER_S;
+ monotonic_time.tv_sec += 1;
+ } else if (monotonic_time.tv_nsec < 0) {
+ monotonic_time.tv_nsec += NS_PER_S;
+ monotonic_time.tv_sec -= 1;
+ }
+ monotonic_time.tv_sec -= cur_realtime_time.tv_sec;
+ monotonic_time.tv_sec += cur_monotonic_time.tv_sec;
+}
diff --git a/libc/bionic/c16rtomb.cpp b/libc/bionic/c16rtomb.cpp
index 77512be..93749c6 100644
--- a/libc/bionic/c16rtomb.cpp
+++ b/libc/bionic/c16rtomb.cpp
@@ -50,18 +50,18 @@
mbstate_set_byte(state, 2, (c32 & 0x00ff00) >> 8);
return 0;
} else if (is_low_surrogate(c16)) {
- return reset_and_return_illegal(EINVAL, state);
+ return mbstate_reset_and_return_illegal(EINVAL, state);
} else {
return c32rtomb(s, static_cast<char32_t>(c16), state);
}
} else {
if (!is_low_surrogate(c16)) {
- return reset_and_return_illegal(EINVAL, state);
+ return mbstate_reset_and_return_illegal(EINVAL, state);
}
char32_t c32 = ((mbstate_get_byte(state, 3) << 16) |
(mbstate_get_byte(state, 2) << 8) |
(c16 & ~0xdc00)) + 0x10000;
- return reset_and_return(c32rtomb(s, c32, NULL), state);
+ return mbstate_reset_and_return(c32rtomb(s, c32, NULL), state);
}
}
diff --git a/libc/bionic/c32rtomb.cpp b/libc/bionic/c32rtomb.cpp
index d3231c0..ebe9cd3 100644
--- a/libc/bionic/c32rtomb.cpp
+++ b/libc/bionic/c32rtomb.cpp
@@ -38,7 +38,7 @@
if (s == NULL) {
// Equivalent to c32rtomb(buf, U'\0', ps).
- return reset_and_return(1, state);
+ return mbstate_reset_and_return(1, state);
}
// POSIX states that if char32_t is a null wide character, a null byte shall
@@ -47,11 +47,11 @@
// stored.
if (c32 == U'\0') {
*s = '\0';
- reset_and_return(1, state);
+ return mbstate_reset_and_return(1, state);
}
if (!mbsinit(state)) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if ((c32 & ~0x7f) == 0) {
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 144e133..4b7b776 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -55,8 +55,6 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
-
#include <poll.h>
#include <stdarg.h>
#include <stddef.h>
@@ -80,8 +78,6 @@
// http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
//
-struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
-
int __FD_ISSET_chk(int fd, fd_set* set, size_t set_size) {
__check_fd_set("FD_ISSET", fd, set_size);
return FD_ISSET(fd, set);
@@ -105,8 +101,7 @@
return fgets(dst, supplied_size, stream);
}
-size_t __fread_chk(void* __restrict buf, size_t size, size_t count,
- FILE* __restrict stream, size_t buf_size) {
+size_t __fread_chk(void* buf, size_t size, size_t count, FILE* stream, size_t buf_size) {
size_t total;
if (__predict_false(__size_mul_overflow(size, count, &total))) {
// overflow: trigger the error path in fread
@@ -116,8 +111,7 @@
return fread(buf, size, count, stream);
}
-size_t __fwrite_chk(const void* __restrict buf, size_t size, size_t count,
- FILE* __restrict stream, size_t buf_size) {
+size_t __fwrite_chk(const void* buf, size_t size, size_t count, FILE* stream, size_t buf_size) {
size_t total;
if (__predict_false(__size_mul_overflow(size, count, &total))) {
// overflow: trigger the error path in fwrite
@@ -153,7 +147,7 @@
void* __memrchr_chk(const void* s, int c, size_t n, size_t actual_size) {
__check_buffer_access("memrchr", "read from", n, actual_size);
- return memrchr(s, c, n);
+ return memrchr(const_cast<void *>(s), c, n);
}
// memset is performance-critical enough that we have assembler __memset_chk implementations.
@@ -241,8 +235,7 @@
}
// Runtime implementation of __builtin____stpncpy_chk (used directly by compiler, not in headers).
-extern "C" char* __stpncpy_chk(char* __restrict dst, const char* __restrict src,
- size_t len, size_t dst_len) {
+extern "C" char* __stpncpy_chk(char* dst, const char* src, size_t len, size_t dst_len) {
__check_buffer_access("stpncpy", "write into", len, dst_len);
return stpncpy(dst, src, len);
}
@@ -251,8 +244,7 @@
// sure we don't read beyond the end of "src". The code for this is
// based on the original version of stpncpy, but modified to check
// how much we read from "src" at the end of the copy operation.
-char* __stpncpy_chk2(char* __restrict dst, const char* __restrict src,
- size_t n, size_t dst_len, size_t src_len) {
+char* __stpncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_t src_len) {
__check_buffer_access("stpncpy", "write into", n, dst_len);
if (n != 0) {
char* d = dst;
@@ -327,8 +319,7 @@
}
// Runtime implementation of __builtin____strncat_chk (used directly by compiler, not in headers).
-extern "C" char* __strncat_chk(char* __restrict dst, const char* __restrict src,
- size_t len, size_t dst_buf_size) {
+extern "C" char* __strncat_chk(char* dst, const char* src, size_t len, size_t dst_buf_size) {
if (len == 0) {
return dst;
}
@@ -355,8 +346,7 @@
}
// Runtime implementation of __builtin____strncpy_chk (used directly by compiler, not in headers).
-extern "C" char* __strncpy_chk(char* __restrict dst, const char* __restrict src,
- size_t len, size_t dst_len) {
+extern "C" char* __strncpy_chk(char* dst, const char* src, size_t len, size_t dst_len) {
__check_buffer_access("strncpy", "write into", len, dst_len);
return strncpy(dst, src, len);
}
@@ -365,8 +355,7 @@
// sure we don't read beyond the end of "src". The code for this is
// based on the original version of strncpy, but modified to check
// how much we read from "src" at the end of the copy operation.
-char* __strncpy_chk2(char* __restrict dst, const char* __restrict src,
- size_t n, size_t dst_len, size_t src_len) {
+char* __strncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_t src_len) {
__check_buffer_access("strncpy", "write into", n, dst_len);
if (n != 0) {
char* d = dst;
@@ -458,3 +447,42 @@
__check_buffer_access("write", "read from", count, buf_size);
return write(fd, buf, count);
}
+
+#if !defined(NO___STRCAT_CHK)
+// Runtime implementation of __builtin____strcat_chk (used directly by compiler, not in headers).
+extern "C" char* __strcat_chk(char* dst, const char* src, size_t dst_buf_size) {
+ char* save = dst;
+ size_t dst_len = __strlen_chk(dst, dst_buf_size);
+
+ dst += dst_len;
+ dst_buf_size -= dst_len;
+
+ while ((*dst++ = *src++) != '\0') {
+ dst_buf_size--;
+ if (__predict_false(dst_buf_size == 0)) {
+ __fortify_fatal("strcat: prevented write past end of %zu-byte buffer", dst_buf_size);
+ }
+ }
+
+ return save;
+}
+#endif // NO___STRCAT_CHK
+
+#if !defined(NO___STRCPY_CHK)
+// Runtime implementation of __builtin____strcpy_chk (used directly by compiler, not in headers).
+extern "C" char* __strcpy_chk(char* dst, const char* src, size_t dst_len) {
+ // TODO: optimize so we don't scan src twice.
+ size_t src_len = strlen(src) + 1;
+ __check_buffer_access("strcpy", "write into", src_len, dst_len);
+ return strcpy(dst, src);
+}
+#endif // NO___STRCPY_CHK
+
+#if !defined(NO___MEMCPY_CHK)
+// Runtime implementation of __memcpy_chk (used directly by compiler, not in headers).
+extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
+ __check_count("memcpy", "count", count);
+ __check_buffer_access("memcpy", "write into", count, dst_len);
+ return memcpy(dst, src, count);
+}
+#endif // NO___MEMCPY_CHK
diff --git a/libc/bionic/getcwd.cpp b/libc/bionic/getcwd.cpp
index c2a7e23..50487ec 100644
--- a/libc/bionic/getcwd.cpp
+++ b/libc/bionic/getcwd.cpp
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
#include <errno.h>
#include <malloc.h>
#include <string.h>
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index 078a0b3..2823662 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -467,7 +467,16 @@
char* getlogin() { // NOLINT: implementing bad function.
passwd *pw = getpwuid(getuid()); // NOLINT: implementing bad function in terms of bad function.
- return (pw != NULL) ? pw->pw_name : NULL;
+ return pw ? pw->pw_name : nullptr;
+}
+
+int getlogin_r(char* buf, size_t size) {
+ char* login = getlogin();
+ if (login == nullptr) return errno;
+ size_t login_length = strlen(login) + 1;
+ if (login_length > size) return ERANGE;
+ memcpy(buf, login, login_length);
+ return 0;
}
void setpwent() {
diff --git a/libc/bionic/iconv.cpp b/libc/bionic/iconv.cpp
new file mode 100644
index 0000000..b0372a1
--- /dev/null
+++ b/libc/bionic/iconv.cpp
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2017 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 <iconv.h>
+
+#include <ctype.h>
+#include <endian.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <uchar.h>
+
+#include "private/bionic_mbstate.h"
+
+#define INVALID_ICONV_T reinterpret_cast<iconv_t>(-1)
+
+// Ideally we'd use icu4c but the API mismatch seems too great. So we just offer something
+// equivalent to (but slightly easier to use for runs of text than) <uchar.h>. If you're
+// here to add more encodings, consider working on finishing the icu4c NDK wrappers instead.
+enum Encoding {
+ US_ASCII,
+ UTF_8,
+ UTF_16_LE,
+ UTF_16_BE,
+ UTF_32_LE,
+ UTF_32_BE,
+ WCHAR_T,
+};
+
+enum Mode {
+ ERROR,
+ IGNORE,
+ TRANSLIT,
+};
+
+// This matching is strange but true.
+// See http://www.unicode.org/reports/tr22/#Charset_Alias_Matching.
+static bool __match_encoding(const char* lhs, const char* rhs) {
+ while (*lhs && *rhs) {
+ // Skip non-alnum in lhs; "UTF-8", "UTF_8", "UTF8", "UTF 8" are all equivalent.
+ // Also implement the "delete each 0 that is not preceded by a digit" rule.
+ for (; *lhs; ++lhs) {
+ if (isalnum(*lhs) && (*lhs != '0' || !isdigit(*(lhs + 1)))) break;
+ }
+ // Case doesn't matter either.
+ if (tolower(*lhs) != tolower(*rhs)) break;
+ ++lhs;
+ ++rhs;
+ }
+ // As a special case we treat the GNU "//" extensions as end of string.
+ if ((*lhs == '\0' || strstr(lhs, "//") == lhs) && *rhs == '\0') return true;
+ return false;
+}
+
+static bool __parse_encoding(const char* s, Encoding* encoding, Mode* mode) {
+ const char* suffix = strstr(s, "//");
+ if (suffix) {
+ if (!mode) return false;
+ if (strcmp(suffix, "//IGNORE") == 0) {
+ *mode = IGNORE;
+ } else if (strcmp(suffix, "//TRANSLIT") == 0) {
+ *mode = TRANSLIT;
+ } else {
+ return false;
+ }
+ }
+ if (__match_encoding(s, "utf8")) {
+ *encoding = UTF_8;
+ } else if (__match_encoding(s, "ascii") || __match_encoding(s, "usascii")) {
+ *encoding = US_ASCII;
+ } else if (__match_encoding(s, "utf16le")) {
+ *encoding = UTF_16_LE;
+ } else if (__match_encoding(s, "utf16be")) {
+ *encoding = UTF_16_BE;
+ } else if (__match_encoding(s, "utf32le")) {
+ *encoding = UTF_32_LE;
+ } else if (__match_encoding(s, "utf32be")) {
+ *encoding = UTF_32_BE;
+ } else if (__match_encoding(s, "wchart")) {
+ *encoding = WCHAR_T;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+struct __iconv_t {
+ Encoding src_encoding;
+ Encoding dst_encoding;
+ Mode mode;
+
+ __iconv_t() : mode(ERROR) {
+ }
+
+ int Convert(char** src_buf0, size_t* src_bytes_left0, char** dst_buf0, size_t* dst_bytes_left0) {
+ // Reset state.
+ wc = 0;
+ memset(&ps, 0, sizeof(ps));
+ replacement_count = 0;
+ ignored = false;
+ src_buf = src_buf0;
+ src_bytes_left = src_bytes_left0;
+ dst_buf = dst_buf0;
+ dst_bytes_left = dst_bytes_left0;
+
+ while (*src_bytes_left > 0) {
+ if (!GetNext() || !Convert()) return -1;
+ }
+ return Done();
+ }
+
+ private:
+ char32_t wc;
+ char buf[16];
+ size_t src_bytes_used;
+ size_t dst_bytes_used;
+ mbstate_t ps;
+
+ size_t replacement_count;
+ bool ignored;
+
+ char** src_buf;
+ size_t* src_bytes_left;
+ char** dst_buf;
+ size_t* dst_bytes_left;
+
+ bool GetNext() {
+ errno = 0;
+ switch (src_encoding) {
+ case US_ASCII:
+ wc = **src_buf;
+ src_bytes_used = 1;
+ if (wc > 0x7f) errno = EILSEQ;
+ break;
+
+ case UTF_8:
+ src_bytes_used = mbrtoc32(&wc, *src_buf, *src_bytes_left, &ps);
+ if (src_bytes_used == __MB_ERR_ILLEGAL_SEQUENCE) {
+ break; // EILSEQ already set.
+ } else if (src_bytes_used == __MB_ERR_INCOMPLETE_SEQUENCE) {
+ errno = EINVAL;
+ return false;
+ }
+ break;
+
+ case UTF_16_BE:
+ case UTF_16_LE: {
+ if (*src_bytes_left < 2) {
+ errno = EINVAL;
+ return false;
+ }
+ bool swap = (src_encoding == UTF_16_BE);
+ wc = In16(*src_buf, swap);
+ // 0xd800-0xdbff: high surrogates
+ // 0xdc00-0xdfff: low surrogates
+ if (wc >= 0xd800 && wc <= 0xdfff) {
+ if (wc >= 0xdc00) { // Low surrogate before high surrogate.
+ errno = EILSEQ;
+ return false;
+ }
+ if (*src_bytes_left < 4) {
+ errno = EINVAL;
+ return false;
+ }
+ uint16_t hi = wc;
+ uint16_t lo = In16(*src_buf + 2, swap);
+ wc = 0x10000 + ((hi - 0xd800) << 10) + (lo - 0xdc00);
+ src_bytes_used = 4;
+ }
+ break;
+ }
+
+ case UTF_32_BE:
+ case UTF_32_LE:
+ case WCHAR_T:
+ if (*src_bytes_left < 4) {
+ errno = EINVAL;
+ return false;
+ }
+ wc = In32(*src_buf, (src_encoding == UTF_32_BE));
+ break;
+ }
+
+ if (errno == EILSEQ) {
+ switch (mode) {
+ case ERROR:
+ return false;
+ case IGNORE:
+ *src_buf += src_bytes_used;
+ *src_bytes_left -= src_bytes_used;
+ ignored = true;
+ return GetNext();
+ case TRANSLIT:
+ wc = '?';
+ ++replacement_count;
+ return true;
+ }
+ }
+ return true;
+ }
+
+ bool Convert() {
+ errno = 0;
+ switch (dst_encoding) {
+ case US_ASCII:
+ buf[0] = wc;
+ dst_bytes_used = 1;
+ if (wc > 0x7f) errno = EILSEQ;
+ break;
+
+ case UTF_8:
+ dst_bytes_used = c32rtomb(buf, wc, &ps);
+ if (dst_bytes_used == __MB_ERR_ILLEGAL_SEQUENCE) {
+ break; // EILSEQ already set.
+ } else if (dst_bytes_used == __MB_ERR_INCOMPLETE_SEQUENCE) {
+ errno = EINVAL;
+ return false;
+ }
+ break;
+
+ case UTF_16_BE:
+ case UTF_16_LE: {
+ bool swap = (dst_encoding == UTF_16_BE);
+ if (wc < 0x10000) { // BMP.
+ Out16(buf, wc, swap);
+ } else { // Supplementary plane; output surrogate pair.
+ wc -= 0x10000;
+ char16_t hi = 0xd800 | (wc >> 10);
+ char16_t lo = 0xdc00 | (wc & 0x3ff);
+ Out16(buf + 0, hi, swap);
+ Out16(buf + 2, lo, swap);
+ dst_bytes_used = 4;
+ }
+ } break;
+
+ case UTF_32_BE:
+ case UTF_32_LE:
+ case WCHAR_T:
+ Out32(wc, (dst_encoding == UTF_32_BE));
+ break;
+ }
+
+ if (errno == EILSEQ) {
+ if (mode == IGNORE) {
+ *src_buf += src_bytes_used;
+ *src_bytes_left -= src_bytes_used;
+ ignored = true;
+ return true;
+ } else if (mode == TRANSLIT) {
+ wc = '?';
+ ++replacement_count;
+ return Convert();
+ }
+ return false;
+ }
+
+ return Emit();
+ }
+
+ uint16_t In16(const char* buf, bool swap) {
+ const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
+ uint16_t wc = (src[0]) | (src[1] << 8);
+ if (swap) wc = __swap16(wc);
+ src_bytes_used = 2;
+ return wc;
+ }
+
+ uint32_t In32(const char* buf, bool swap) {
+ const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
+ uint32_t wc = (src[0]) | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+ if (swap) wc = __swap32(wc);
+ src_bytes_used = 4;
+ return wc;
+ }
+
+ void Out16(char* dst, char16_t ch, bool swap) {
+ if (swap) ch = __swap16(ch);
+ dst[0] = ch;
+ dst[1] = ch >> 8;
+ dst_bytes_used = 2;
+ }
+
+ void Out32(char32_t ch, bool swap) {
+ if (swap) ch = __swap32(ch);
+ buf[0] = ch;
+ buf[1] = ch >> 8;
+ buf[2] = ch >> 16;
+ buf[3] = ch >> 24;
+ dst_bytes_used = 4;
+ }
+
+ bool Emit() {
+ if (dst_bytes_used > *dst_bytes_left) {
+ errno = E2BIG;
+ return false;
+ }
+
+ memcpy(*dst_buf, buf, dst_bytes_used);
+ *src_buf += src_bytes_used;
+ *src_bytes_left -= src_bytes_used;
+ *dst_buf += dst_bytes_used;
+ *dst_bytes_left -= dst_bytes_used;
+ return true;
+ }
+
+ int Done() {
+ if (mode == TRANSLIT) return replacement_count;
+ if (ignored) {
+ errno = EILSEQ;
+ return -1;
+ }
+ return 0;
+ }
+};
+
+iconv_t iconv_open(const char* __dst_encoding, const char* __src_encoding) {
+ iconv_t result = new __iconv_t;
+ if (!__parse_encoding(__src_encoding, &result->src_encoding, nullptr) ||
+ !__parse_encoding(__dst_encoding, &result->dst_encoding, &result->mode)) {
+ delete result;
+ errno = EINVAL;
+ return INVALID_ICONV_T;
+ }
+ return result;
+}
+
+size_t iconv(iconv_t __converter,
+ char** __src_buf, size_t* __src_bytes_left,
+ char** __dst_buf, size_t* __dst_bytes_left) {
+ if (__converter == INVALID_ICONV_T) {
+ errno = EBADF;
+ return -1;
+ }
+ return __converter->Convert(__src_buf, __src_bytes_left, __dst_buf, __dst_bytes_left);
+}
+
+int iconv_close(iconv_t __converter) {
+ if (__converter == INVALID_ICONV_T) {
+ errno = EBADF;
+ return -1;
+ }
+ delete __converter;
+ return 0;
+}
diff --git a/libc/bionic/icu_wrappers.cpp b/libc/bionic/icu_wrappers.cpp
new file mode 100644
index 0000000..d9f2745
--- /dev/null
+++ b/libc/bionic/icu_wrappers.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "private/icu.h"
+
+int8_t __icu_charType(wint_t wc) {
+ typedef int8_t (*u_charType_t)(UChar32);
+ static auto u_charType = reinterpret_cast<u_charType_t>(__find_icu_symbol("u_charType"));
+ return u_charType ? u_charType(wc) : -1;
+}
+
+int32_t __icu_getIntPropertyValue(wint_t wc, UProperty property) {
+ typedef int32_t (*u_getIntPropertyValue_t)(UChar32, UProperty);
+ static auto u_getIntPropertyValue =
+ reinterpret_cast<u_getIntPropertyValue_t>(__find_icu_symbol("u_getIntPropertyValue"));
+ return u_getIntPropertyValue ? u_getIntPropertyValue(wc, property) : 0;
+}
+
+bool __icu_hasBinaryProperty(wint_t wc, UProperty property, int (*fallback)(int)) {
+ typedef UBool (*u_hasBinaryProperty_t)(UChar32, UProperty);
+ static auto u_hasBinaryProperty =
+ reinterpret_cast<u_hasBinaryProperty_t>(__find_icu_symbol("u_hasBinaryProperty"));
+ return u_hasBinaryProperty ? u_hasBinaryProperty(wc, property) : fallback(wc);
+}
diff --git a/libc/bionic/__memcpy_chk.cpp b/libc/bionic/killpg.cpp
similarity index 74%
copy from libc/bionic/__memcpy_chk.cpp
copy to libc/bionic/killpg.cpp
index 7b42d99..01a58b3 100644
--- a/libc/bionic/__memcpy_chk.cpp
+++ b/libc/bionic/killpg.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,15 +26,13 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
+#include <errno.h>
+#include <signal.h>
-#include <string.h>
-
-#include "private/bionic_fortify.h"
-
-// Runtime implementation of __memcpy_chk (used directly by compiler, not in headers).
-extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
- __check_count("memcpy", "count", count);
- __check_buffer_access("memcpy", "write into", count, dst_len);
- return memcpy(dst, src, count);
+int killpg(pid_t pgrp, int sig) {
+ if (pgrp < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ return kill(-pgrp, sig);
}
diff --git a/libc/bionic/mbrtoc16.cpp b/libc/bionic/mbrtoc16.cpp
index 6878a11..2180516 100644
--- a/libc/bionic/mbrtoc16.cpp
+++ b/libc/bionic/mbrtoc16.cpp
@@ -55,7 +55,7 @@
char16_t trail = mbstate_get_byte(state, 1) << 8 |
mbstate_get_byte(state, 0);
*pc16 = trail;
- return reset_and_return(mbstate_get_byte(state, 3), state);
+ return mbstate_reset_and_return(mbstate_get_byte(state, 3), state);
}
size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps) {
@@ -76,13 +76,13 @@
if (__MB_IS_ERR(nconv)) {
return nconv;
} else if (nconv == 0) {
- return reset_and_return(nconv, state);
+ return mbstate_reset_and_return(nconv, state);
} else if (c32 > 0x10ffff) {
// Input cannot be encoded as UTF-16.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
} else if (c32 < 0x10000) {
*pc16 = static_cast<char16_t>(c32);
- return reset_and_return(nconv, state);
+ return mbstate_reset_and_return(nconv, state);
} else {
return begin_surrogate(c32, pc16, nconv, state);
}
diff --git a/libc/bionic/mbrtoc32.cpp b/libc/bionic/mbrtoc32.cpp
index bd40ecf..f004b78 100644
--- a/libc/bionic/mbrtoc32.cpp
+++ b/libc/bionic/mbrtoc32.cpp
@@ -41,7 +41,7 @@
// Full state verification is done when decoding the sequence (after we have
// all the bytes).
if (mbstate_get_byte(state, 3) != 0) {
- return reset_and_return_illegal(EINVAL, state);
+ return mbstate_reset_and_return_illegal(EINVAL, state);
}
if (s == NULL) {
@@ -98,7 +98,7 @@
lower_bound = 0x10000;
} else {
// Malformed input; input is not UTF-8. See RFC 3629.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
// Fill in the state.
@@ -107,7 +107,7 @@
for (i = 0; i < MIN(bytes_wanted, n); i++) {
if (!mbsinit(state) && ((*s & 0xc0) != 0x80)) {
// Malformed input; bad characters in the middle of a character.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
mbstate_set_byte(state, bytes_so_far + i, *s++);
}
@@ -125,14 +125,14 @@
if (c32 < lower_bound) {
// Malformed input; redundant encoding.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if ((c32 >= 0xd800 && c32 <= 0xdfff) || c32 == 0xfffe || c32 == 0xffff) {
// Malformed input; invalid code points.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (pc32 != NULL) {
*pc32 = c32;
}
- return reset_and_return(c32 == U'\0' ? 0 : bytes_wanted, state);
+ return mbstate_reset_and_return(c32 == U'\0' ? 0 : bytes_wanted, state);
}
diff --git a/libc/bionic/mbstate.cpp b/libc/bionic/mbstate.cpp
deleted file mode 100644
index cb327d8..0000000
--- a/libc/bionic/mbstate.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "private/bionic_mbstate.h"
-
-#include <errno.h>
-
-__LIBC_HIDDEN__ size_t mbstate_bytes_so_far(const mbstate_t* ps) {
- return
- (ps->__seq[2] != 0) ? 3 :
- (ps->__seq[1] != 0) ? 2 :
- (ps->__seq[0] != 0) ? 1 : 0;
-}
-
-__LIBC_HIDDEN__ void mbstate_set_byte(mbstate_t* ps, int i, char byte) {
- ps->__seq[i] = static_cast<uint8_t>(byte);
-}
-
-__LIBC_HIDDEN__ uint8_t mbstate_get_byte(const mbstate_t* ps, int n) {
- return ps->__seq[n];
-}
-
-__LIBC_HIDDEN__ size_t reset_and_return_illegal(int _errno, mbstate_t* ps) {
- errno = _errno;
- *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
- return __MB_ERR_ILLEGAL_SEQUENCE;
-}
-
-__LIBC_HIDDEN__ size_t reset_and_return(int _return, mbstate_t* ps) {
- *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
- return _return;
-}
diff --git a/libc/bionic/open.cpp b/libc/bionic/open.cpp
index 6d179c4..222e5d3 100644
--- a/libc/bionic/open.cpp
+++ b/libc/bionic/open.cpp
@@ -43,6 +43,10 @@
#endif
}
+static inline bool needs_mode(int flags) {
+ return ((flags & O_CREAT) == O_CREAT) || ((flags & O_TMPFILE) == O_TMPFILE);
+}
+
int creat(const char* pathname, mode_t mode) {
return open(pathname, O_CREAT | O_TRUNC | O_WRONLY, mode);
}
@@ -51,7 +55,7 @@
int open(const char* pathname, int flags, ...) {
mode_t mode = 0;
- if ((flags & O_CREAT) != 0) {
+ if (needs_mode(flags)) {
va_list args;
va_start(args, flags);
mode = static_cast<mode_t>(va_arg(args, int));
@@ -63,17 +67,14 @@
__strong_alias(open64, open);
int __open_2(const char* pathname, int flags) {
- if (__predict_false((flags & O_CREAT) != 0)) {
- __fortify_fatal("open(O_CREAT): called without specifying a mode");
- }
-
+ if (needs_mode(flags)) __fortify_fatal("open: called with O_CREAT/O_TMPFILE but no mode");
return __openat(AT_FDCWD, pathname, force_O_LARGEFILE(flags), 0);
}
int openat(int fd, const char *pathname, int flags, ...) {
mode_t mode = 0;
- if ((flags & O_CREAT) != 0) {
+ if (needs_mode(flags)) {
va_list args;
va_start(args, flags);
mode = static_cast<mode_t>(va_arg(args, int));
@@ -85,9 +86,6 @@
__strong_alias(openat64, openat);
int __openat_2(int fd, const char* pathname, int flags) {
- if ((flags & O_CREAT) != 0) {
- __fortify_fatal("openat(O_CREAT): called without specifying a mode");
- }
-
+ if (needs_mode(flags)) __fortify_fatal("open: called with O_CREAT/O_TMPFILE but no mode");
return __openat(fd, pathname, force_O_LARGEFILE(flags), 0);
}
diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp
index eded56a..dbc9584 100644
--- a/libc/bionic/poll.cpp
+++ b/libc/bionic/poll.cpp
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
#include <errno.h>
#include <sys/poll.h>
#include <sys/select.h>
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 9197aa3..9be86f1 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -278,7 +278,7 @@
munmap(thread->attr.stack_base, thread->mmap_size);
}
async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %s",
- strerror(errno));
+ strerror(clone_errno));
return clone_errno;
}
diff --git a/libc/bionic/readlink.cpp b/libc/bionic/readlink.cpp
index a53f933..3bb7bc1 100644
--- a/libc/bionic/readlink.cpp
+++ b/libc/bionic/readlink.cpp
@@ -26,8 +26,6 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
-
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
diff --git a/libc/bionic/recv.cpp b/libc/bionic/recv.cpp
index 061cd46..60f264d 100644
--- a/libc/bionic/recv.cpp
+++ b/libc/bionic/recv.cpp
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
#include <sys/socket.h>
ssize_t recv(int socket, void *buf, size_t len, int flags) {
diff --git a/libc/bionic/strchr.cpp b/libc/bionic/strchr.cpp
index 5bd3f19..fd8a924 100644
--- a/libc/bionic/strchr.cpp
+++ b/libc/bionic/strchr.cpp
@@ -27,7 +27,6 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
#include <string.h>
char* strchr(const char* p, int ch) {
diff --git a/libc/bionic/strrchr.cpp b/libc/bionic/strrchr.cpp
index 3fdb47c..b6c40f4 100644
--- a/libc/bionic/strrchr.cpp
+++ b/libc/bionic/strrchr.cpp
@@ -27,7 +27,6 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
#include <string.h>
char* strrchr(const char* p, int ch) {
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 4a23fec..7325dbd 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -135,12 +135,12 @@
case _SC_TIMERS: return _POSIX_TIMERS;
case _SC_GETGR_R_SIZE_MAX: return 1024;
case _SC_GETPW_R_SIZE_MAX: return 1024;
- case _SC_LOGIN_NAME_MAX: return 256; // Seems default on linux.
+ case _SC_LOGIN_NAME_MAX: return LOGIN_NAME_MAX;
case _SC_THREAD_DESTRUCTOR_ITERATIONS: return PTHREAD_DESTRUCTOR_ITERATIONS;
case _SC_THREAD_KEYS_MAX: return PTHREAD_KEYS_MAX;
case _SC_THREAD_STACK_MIN: return PTHREAD_STACK_MIN;
case _SC_THREAD_THREADS_MAX: return -1; // No specific limit.
- case _SC_TTY_NAME_MAX: return 32; // Seems default on linux.
+ case _SC_TTY_NAME_MAX: return TTY_NAME_MAX;
case _SC_THREADS: return _POSIX_THREADS;
case _SC_THREAD_ATTR_STACKADDR: return _POSIX_THREAD_ATTR_STACKADDR;
case _SC_THREAD_ATTR_STACKSIZE: return _POSIX_THREAD_ATTR_STACKSIZE;
diff --git a/libc/bionic/sysinfo.cpp b/libc/bionic/sysinfo.cpp
index 304634a..947de95 100644
--- a/libc/bionic/sysinfo.cpp
+++ b/libc/bionic/sysinfo.cpp
@@ -79,11 +79,11 @@
long get_phys_pages() {
struct sysinfo si;
sysinfo(&si);
- return (si.totalram * si.mem_unit) / sysconf(_SC_PAGE_SIZE);
+ return (static_cast<int64_t>(si.totalram) * si.mem_unit) / PAGE_SIZE;
}
long get_avphys_pages() {
struct sysinfo si;
sysinfo(&si);
- return ((si.freeram + si.bufferram) * si.mem_unit) / sysconf(_SC_PAGE_SIZE);
+ return ((static_cast<int64_t>(si.freeram) + si.bufferram) * si.mem_unit) / PAGE_SIZE;
}
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index a958699..6906ecd 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -1051,16 +1051,15 @@
if (!initialize_properties_from_file("/system/etc/selinux/plat_property_contexts")) {
return false;
}
- if (!initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts")) {
- return false;
- }
+ // Don't check for failure here, so we always have a sane list of properties.
+ // E.g. In case of recovery, the vendor partition will not have mounted and we
+ // still need the system / platform properties to function.
+ initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts");
} else {
if (!initialize_properties_from_file("/plat_property_contexts")) {
return false;
}
- if (!initialize_properties_from_file("/nonplat_property_contexts")) {
- return false;
- }
+ initialize_properties_from_file("/nonplat_property_contexts");
}
return true;
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp
index 36fc2a2..62023d6 100644
--- a/libc/bionic/wchar.cpp
+++ b/libc/bionic/wchar.cpp
@@ -74,7 +74,7 @@
// character appears as anything but the first byte of a
// multibyte sequence. Check now to avoid doing it in the loops.
if (nmc > 0 && mbstate_bytes_so_far(state) > 0 && static_cast<uint8_t>((*src)[0]) < 0x80) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
// Measure only?
@@ -83,23 +83,23 @@
if (static_cast<uint8_t>((*src)[i]) < 0x80) {
// Fast path for plain ASCII characters.
if ((*src)[i] == '\0') {
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
r = 1;
} else {
r = mbrtowc(NULL, *src + i, nmc - i, state);
if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (r == 0) {
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
}
}
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
// Actually convert, updating `dst` and `src`.
@@ -110,26 +110,26 @@
r = 1;
if ((*src)[i] == '\0') {
*src = nullptr;
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
} else {
r = mbrtowc(dst + o, *src + i, nmc - i, state);
if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
*src += i;
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
*src += nmc;
- return reset_and_return(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (r == 0) {
*src = NULL;
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
}
}
*src += i;
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps) {
@@ -149,7 +149,7 @@
mbstate_t* state = (ps == NULL) ? &__private_state : ps;
if (!mbsinit(state)) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
char buf[MB_LEN_MAX];
diff --git a/libc/bionic/wctype.cpp b/libc/bionic/wctype.cpp
index 8e2acef..05b6e19 100644
--- a/libc/bionic/wctype.cpp
+++ b/libc/bionic/wctype.cpp
@@ -53,12 +53,6 @@
WC_TYPE_MAX
};
-static bool __icu_hasBinaryProperty(wint_t wc, UProperty property, int (*fallback)(int)) {
- typedef UBool (*FnT)(UChar32, UProperty);
- static auto u_hasBinaryProperty = reinterpret_cast<FnT>(__find_icu_symbol("u_hasBinaryProperty"));
- return u_hasBinaryProperty ? u_hasBinaryProperty(wc, property) : fallback(wc);
-}
-
int iswalnum(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_ALNUM, isalnum); }
int iswalpha(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_ALPHABETIC, isalpha); }
int iswblank(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_BLANK, isblank); }
@@ -155,10 +149,6 @@
return wctype(property);
}
-int wcwidth(wchar_t wc) {
- return (wc > 0);
-}
-
static wctrans_t wctrans_tolower = wctrans_t(1);
static wctrans_t wctrans_toupper = wctrans_t(2);
diff --git a/libc/bionic/wcwidth.cpp b/libc/bionic/wcwidth.cpp
new file mode 100644
index 0000000..9676b5a
--- /dev/null
+++ b/libc/bionic/wcwidth.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2017 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 <wchar.h>
+
+#include "private/icu.h"
+
+int wcwidth(wchar_t wc) {
+ // Fast-path ASCII.
+ if (wc >= 0x20 && wc < 0x7f) return 1;
+
+ // ASCII NUL is a special case.
+ if (wc == 0) return 0;
+
+ // C0.
+ if (wc < ' ' || (wc >= 0x7f && wc <= 0xa0)) return -1;
+
+ // Now for the i18n part. This isn't defined or standardized, so a lot of the choices are
+ // pretty arbitrary. See https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c for more details.
+
+ // Fancy unicode control characters?
+ switch (__icu_charType(wc)) {
+ case -1:
+ // No icu4c available; give up.
+ return -1;
+ case U_CONTROL_CHAR:
+ return -1;
+ case U_NON_SPACING_MARK:
+ case U_ENCLOSING_MARK:
+ case U_FORMAT_CHAR:
+ return 0;
+ }
+ if (__icu_hasBinaryProperty(wc, UCHAR_DEFAULT_IGNORABLE_CODE_POINT, nullptr)) return 0;
+
+ // Medial and final jamo render as zero width when used correctly.
+ switch (__icu_getIntPropertyValue(wc, UCHAR_HANGUL_SYLLABLE_TYPE)) {
+ case U_HST_VOWEL_JAMO:
+ case U_HST_TRAILING_JAMO:
+ return 0;
+ case U_HST_LEADING_JAMO:
+ case U_HST_LV_SYLLABLE:
+ case U_HST_LVT_SYLLABLE:
+ return 2;
+ }
+
+ if (wc >= 0x3248 && wc <= 0x4dff) {
+ // Circled two-digit CJK "speed sign" numbers. EastAsianWidth is ambiguous,
+ // but wide makes more sense.
+ if (wc <= 0x324f) return 2;
+ // Hexagrams. EastAsianWidth is neutral, but wide seems better.
+ if (wc >= 0x4dc0) return 2;
+ }
+
+ // The EastAsianWidth property is at least defined by the Unicode standard!
+ switch (__icu_getIntPropertyValue(wc, UCHAR_EAST_ASIAN_WIDTH)) {
+ case U_EA_AMBIGUOUS:
+ case U_EA_HALFWIDTH:
+ case U_EA_NARROW:
+ case U_EA_NEUTRAL:
+ return 1;
+ case U_EA_FULLWIDTH:
+ case U_EA_WIDE:
+ return 2;
+ }
+
+ return 0;
+}
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index c83c18d..7e3aa99 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -41,6 +41,8 @@
#ifndef __ANDROID_API__
#define __ANDROID_API__ __ANDROID_API_FUTURE__
+#else
+#define __ANDROID_NDK__ 1
#endif
#define __ANDROID_API_G__ 9
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index ca3bd25..c824544 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -129,7 +129,7 @@
struct android_namespace_t* library_namespace;
} android_dlextinfo;
-void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo)
+void* android_dlopen_ext(const char* __filename, int __flags, const android_dlextinfo* __info)
__INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h
index 09db2a6..4d474b0 100644
--- a/libc/include/android/legacy_signal_inlines.h
+++ b/libc/include/android/legacy_signal_inlines.h
@@ -39,7 +39,7 @@
#if __ANDROID_API__ < __ANDROID_API_L__
-sighandler_t bsd_signal(int signum, sighandler_t handler) __REMOVED_IN(21);
+sighandler_t bsd_signal(int __signal, sighandler_t __handler) __REMOVED_IN(21);
/* These weren't introduced until L. */
int __libc_current_sigrtmax() __attribute__((__weak__)) __VERSIONER_NO_GUARD;
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index 82186c7..0d6f2c2 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -29,6 +29,8 @@
#ifndef _ANDROID_LEGACY_STDLIB_INLINES_H_
#define _ANDROID_LEGACY_STDLIB_INLINES_H_
+#include <errno.h>
+#include <float.h>
#include <stdlib.h>
#include <sys/cdefs.h>
@@ -38,8 +40,16 @@
__noreturn void _Exit(int) __RENAME(_exit);
-static __inline float strtof(const char *nptr, char **endptr) {
- return (float)strtod(nptr, endptr);
+static __inline float strtof(const char* nptr, char** endptr) {
+ double d = strtod(nptr, endptr);
+ if (d > FLT_MAX) {
+ errno = ERANGE;
+ return __builtin_huge_valf();
+ } else if (d < -FLT_MAX) {
+ errno = ERANGE;
+ return -__builtin_huge_valf();
+ }
+ return __BIONIC_CAST(static_cast, float, d);
}
static __inline double atof(const char *nptr) { return (strtod(nptr, NULL)); }
diff --git a/libc/include/android/legacy_sys_stat_inlines.h b/libc/include/android/legacy_sys_stat_inlines.h
index 23a9f07..bbf54c0 100644
--- a/libc/include/android/legacy_sys_stat_inlines.h
+++ b/libc/include/android/legacy_sys_stat_inlines.h
@@ -36,8 +36,8 @@
__BEGIN_DECLS
-static __inline int mkfifo(const char *__p, mode_t __m) {
- return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0);
+static __inline int mkfifo(const char* __path, mode_t __mode) {
+ return mknod(__path, (__mode & ~S_IFMT) | S_IFIFO, (dev_t)0);
}
__END_DECLS
diff --git a/libc/include/android/set_abort_message.h b/libc/include/android/set_abort_message.h
index 18881a3..3dde673 100644
--- a/libc/include/android/set_abort_message.h
+++ b/libc/include/android/set_abort_message.h
@@ -33,7 +33,7 @@
__BEGIN_DECLS
-void android_set_abort_message(const char* msg) __INTRODUCED_IN(21);
+void android_set_abort_message(const char* __msg) __INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/arpa/inet.h b/libc/include/arpa/inet.h
index d137130..db054c9 100644
--- a/libc/include/arpa/inet.h
+++ b/libc/include/arpa/inet.h
@@ -36,18 +36,18 @@
__BEGIN_DECLS
-in_addr_t inet_addr(const char*);
-int inet_aton(const char*, struct in_addr*);
-in_addr_t inet_lnaof(struct in_addr) __INTRODUCED_IN(21);
-struct in_addr inet_makeaddr(in_addr_t, in_addr_t) __INTRODUCED_IN(21);
-in_addr_t inet_netof(struct in_addr) __INTRODUCED_IN(21);
-in_addr_t inet_network(const char*) __INTRODUCED_IN(21);
-char* inet_ntoa(struct in_addr);
-const char* inet_ntop(int, const void*, char*, socklen_t);
-unsigned int inet_nsap_addr(const char*, unsigned char*, int);
-char* inet_nsap_ntoa(int, const unsigned char*, char*);
-int inet_pton(int, const char*, void*);
+in_addr_t inet_addr(const char* __s);
+int inet_aton(const char* __s, struct in_addr* __addr);
+in_addr_t inet_lnaof(struct in_addr __addr) __INTRODUCED_IN(21);
+struct in_addr inet_makeaddr(in_addr_t __net, in_addr_t __host) __INTRODUCED_IN(21);
+in_addr_t inet_netof(struct in_addr __addr) __INTRODUCED_IN(21);
+in_addr_t inet_network(const char* __s) __INTRODUCED_IN(21);
+char* inet_ntoa(struct in_addr __addr);
+const char* inet_ntop(int __af, const void* __src, char* __dst, socklen_t __size);
+unsigned int inet_nsap_addr(const char* __ascii, unsigned char* __binary, int __n);
+char* inet_nsap_ntoa(int __binary_length, const unsigned char* __binary, char* __ascii);
+int inet_pton(int __af, const char* __src, void* __dst);
__END_DECLS
-#endif /* _ARPA_INET_H_ */
+#endif
diff --git a/libc/include/arpa/nameser.h b/libc/include/arpa/nameser.h
index 9507f49..ffb5250 100644
--- a/libc/include/arpa/nameser.h
+++ b/libc/include/arpa/nameser.h
@@ -562,63 +562,61 @@
#define ns_makecanon __ns_makecanon
#define ns_samename __ns_samename
-int ns_msg_getflag(ns_msg, int);
-uint16_t ns_get16(const u_char*);
-uint32_t ns_get32(const u_char*);
-void ns_put16(uint16_t, u_char*);
-void ns_put32(uint32_t, u_char*);
-int ns_initparse(const u_char*, int, ns_msg*);
-int ns_skiprr(const u_char*, const u_char*, ns_sect, int);
-int ns_parserr(ns_msg*, ns_sect, int, ns_rr*);
-int ns_sprintrr(const ns_msg*, const ns_rr*, const char*, const char*, char*, size_t);
-int ns_sprintrrf(const u_char*, size_t, const char*, ns_class, ns_type, u_long, const u_char*,
- size_t, const char*, const char*, char*, size_t);
-int ns_format_ttl(u_long, char*, size_t);
-int ns_name_ntol(const u_char*, u_char*, size_t);
-int ns_name_ntop(const u_char*, char*, size_t);
-int ns_name_pton(const char*, u_char*, size_t);
-int ns_name_unpack(const u_char*, const u_char*, const u_char*, u_char*, size_t);
-int ns_name_pack(const u_char*, u_char*, int, const u_char**, const u_char**);
-int ns_name_uncompress(const u_char*, const u_char*, const u_char*, char*, size_t);
-int ns_name_compress(const char*, u_char*, size_t, const u_char**, const u_char**);
-int ns_name_skip(const u_char**, const u_char*);
-void ns_name_rollback(const u_char*, const u_char**, const u_char**);
+int ns_msg_getflag(ns_msg __handle, int __flag);
+uint16_t ns_get16(const u_char* __src);
+uint32_t ns_get32(const u_char* __src);
+void ns_put16(uint16_t __src, u_char* __dst);
+void ns_put32(uint32_t __src, u_char* __dst);
+int ns_initparse(const u_char* __msg, int __msg_size, ns_msg* __handle);
+int ns_skiprr(const u_char* __ptr, const u_char* __eom, ns_sect __section, int __count);
+int ns_parserr(ns_msg* __handle, ns_sect __section, int __rr_number, ns_rr* __rr);
+int ns_sprintrr(const ns_msg* __handle, const ns_rr* __rr, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size);
+int ns_sprintrrf(const u_char* __msg, size_t __msg_size, const char* __name, ns_class __class, ns_type __type, u_long __ttl, const u_char* __rdata, size_t __rdata_size, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size);
+int ns_format_ttl(u_long __ttl, char* __dst, size_t __dst_size);
+int ns_name_ntol(const u_char* __src, u_char* __dst, size_t __dst_size);
+int ns_name_ntop(const u_char* __src, char* __dst, size_t __dst_size);
+int ns_name_pton(const char* __src, u_char* __dst, size_t __dst_size);
+int ns_name_unpack(const u_char* __msg, const u_char* __eom, const u_char* __src, u_char* __dst, size_t __dst_size);
+int ns_name_pack(const u_char* __src, u_char* __dst, int __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr);
+int ns_name_uncompress(const u_char* __msg, const u_char* __eom, const u_char* __src, char* __dst, size_t __dst_size);
+int ns_name_compress(const char* __src, u_char* __dst, size_t __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr);
+int ns_name_skip(const u_char** __ptr_ptr, const u_char* __eom);
+void ns_name_rollback(const u_char* __src, const u_char** __dn_ptrs, const u_char** __last_dn_ptr);
-int ns_makecanon(const char*, char*, size_t);
-int ns_samename(const char*, const char*);
+int ns_makecanon(const char* __src, char* __dst, size_t __dst_size);
+int ns_samename(const char* __lhs, const char* __rhs);
#else
/* The names of these symbols were accidentally prefixed with __ in L. */
/* The duplication here is intentional to avoid declaring different symbols with the same
* declaration. */
-int ns_msg_getflag(ns_msg, int) __INTRODUCED_IN_64(23);
-uint16_t ns_get16(const u_char*) __INTRODUCED_IN_64(23);
-uint32_t ns_get32(const u_char*) __INTRODUCED_IN_64(23);
-void ns_put16(uint16_t, u_char*) __INTRODUCED_IN_64(23);
-void ns_put32(uint32_t, u_char*) __INTRODUCED_IN_64(23);
-int ns_initparse(const u_char*, int, ns_msg*) __INTRODUCED_IN_64(23);
-int ns_skiprr(const u_char*, const u_char*, ns_sect, int) __INTRODUCED_IN_64(23);
-int ns_parserr(ns_msg*, ns_sect, int, ns_rr*) __INTRODUCED_IN_64(23);
-int ns_sprintrr(const ns_msg*, const ns_rr*, const char*, const char*, char*, size_t)
+int ns_msg_getflag(ns_msg __handle, int __flag) __INTRODUCED_IN_64(23);
+uint16_t ns_get16(const u_char* __src) __INTRODUCED_IN_64(23);
+uint32_t ns_get32(const u_char* __src) __INTRODUCED_IN_64(23);
+void ns_put16(uint16_t __src, u_char* __dst) __INTRODUCED_IN_64(23);
+void ns_put32(uint32_t __src, u_char* __dst) __INTRODUCED_IN_64(23);
+int ns_initparse(const u_char* __msg, int __msg_size, ns_msg* __handle) __INTRODUCED_IN_64(23);
+int ns_skiprr(const u_char* __ptr, const u_char* __eom, ns_sect __section, int __count) __INTRODUCED_IN_64(23);
+int ns_parserr(ns_msg* __handle, ns_sect __section, int __rr_number, ns_rr* __rr) __INTRODUCED_IN_64(23);
+int ns_sprintrr(const ns_msg* __handle, const ns_rr* __rr, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size)
__INTRODUCED_IN_64(23);
-int ns_sprintrrf(const u_char*, size_t, const char*, ns_class, ns_type, u_long, const u_char*,
- size_t, const char*, const char*, char*, size_t) __INTRODUCED_IN_64(23);
-int ns_format_ttl(u_long, char*, size_t) __INTRODUCED_IN_64(23);
-int ns_name_ntol(const u_char*, u_char*, size_t) __INTRODUCED_IN_64(23);
-int ns_name_ntop(const u_char*, char*, size_t) __INTRODUCED_IN_64(23);
-int ns_name_pton(const char*, u_char*, size_t) __INTRODUCED_IN_64(23);
-int ns_name_unpack(const u_char*, const u_char*, const u_char*, u_char*, size_t)
+int ns_sprintrrf(const u_char* __msg, size_t __msg_size, const char* __name, ns_class __class, ns_type __type, u_long __ttl, const u_char* __rdata, size_t __rdata_size, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size) __INTRODUCED_IN_64(23);
+int ns_format_ttl(u_long __ttl, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23);
+int ns_name_ntol(const u_char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23);
+int ns_name_ntop(const u_char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23);
+int ns_name_pton(const char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23);
+int ns_name_unpack(const u_char* __msg, const u_char* __eom, const u_char* __src, u_char* __dst, size_t __dst_size)
__INTRODUCED_IN_64(23);
-int ns_name_pack(const u_char*, u_char*, int, const u_char**, const u_char**) __INTRODUCED_IN_64(23);
-int ns_name_uncompress(const u_char*, const u_char*, const u_char*, char*, size_t)
+int ns_name_pack(const u_char* __src, u_char* __dst, int __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(23);
+int ns_name_uncompress(const u_char* __msg, const u_char* __eom, const u_char* __src, char* __dst, size_t __dst_size)
__INTRODUCED_IN_64(23);
-int ns_name_compress(const char*, u_char*, size_t, const u_char**, const u_char**)
+int ns_name_compress(const char* __src, u_char* __dst, size_t __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr)
__INTRODUCED_IN_64(23);
-int ns_name_skip(const u_char**, const u_char*) __INTRODUCED_IN_64(23);
-void ns_name_rollback(const u_char*, const u_char**, const u_char**) __INTRODUCED_IN_64(23);
+int ns_name_skip(const u_char** __ptr_ptr, const u_char* __eom) __INTRODUCED_IN_64(23);
+void ns_name_rollback(const u_char* __src, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(23);
-int ns_makecanon(const char*, char*, size_t) __INTRODUCED_IN_64(23);
-int ns_samename(const char*, const char*) __INTRODUCED_IN_64(23);
+int ns_makecanon(const char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23);
+int ns_samename(const char* __lhs, const char* __rhs) __INTRODUCED_IN_64(23);
#endif /* !defined(__LP64__) */
__END_DECLS
diff --git a/libc/include/assert.h b/libc/include/assert.h
index 8c456ef..7a9d84d 100644
--- a/libc/include/assert.h
+++ b/libc/include/assert.h
@@ -60,6 +60,6 @@
#endif
__BEGIN_DECLS
-void __assert(const char*, int, const char*) __noreturn;
-void __assert2(const char*, int, const char*, const char*) __noreturn;
+void __assert(const char* __file, int __line, const char* __msg) __noreturn;
+void __assert2(const char* __file, int __line, const char* __function, const char* __msg) __noreturn;
__END_DECLS
diff --git a/libc/include/bits/fcntl.h b/libc/include/bits/fcntl.h
index 604d35a..e3b0e8c 100644
--- a/libc/include/bits/fcntl.h
+++ b/libc/include/bits/fcntl.h
@@ -33,7 +33,7 @@
__BEGIN_DECLS
-int fcntl(int, int, ...);
+int fcntl(int __fd, int __cmd, ...);
__END_DECLS
diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h
new file mode 100644
index 0000000..6d90341
--- /dev/null
+++ b/libc/include/bits/fortify/fcntl.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _FCNTL_H
+#error "Never include this file directly; instead, include <fcntl.h>"
+#endif
+
+int __open_2(const char*, int) __INTRODUCED_IN(17);
+int __openat_2(int, const char*, int) __INTRODUCED_IN(17);
+/*
+ * These are the easiest way to call the real open even in clang FORTIFY.
+ */
+int __open_real(const char*, int, ...) __RENAME(open);
+int __openat_real(int, const char*, int, ...) __RENAME(openat);
+
+#if defined(__BIONIC_FORTIFY)
+#define __open_too_many_args_error "too many arguments"
+#define __open_too_few_args_error "called with O_CREAT or O_TMPFILE, but missing mode"
+#define __open_useless_modes_warning "has superfluous mode bits; missing O_CREAT?"
+/* O_TMPFILE shares bits with O_DIRECTORY. */
+#define __open_modes_useful(flags) (((flags) & O_CREAT) || ((flags) & O_TMPFILE) == O_TMPFILE)
+#if defined(__clang__)
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
+ __errorattr(__open_too_many_args_error);
+
+/*
+ * pass_object_size serves two purposes here, neither of which involve __bos: it
+ * disqualifies this function from having its address taken (so &open works),
+ * and it makes overload resolution prefer open(const char *, int) over
+ * open(const char *, int, ...).
+ */
+__BIONIC_FORTIFY_INLINE
+int open(const char* const __pass_object_size pathname, int flags)
+ __overloadable
+ __clang_error_if(__open_modes_useful(flags), "'open' " __open_too_few_args_error) {
+ return __open_2(pathname, flags);
+}
+
+__BIONIC_FORTIFY_INLINE
+int open(const char* const __pass_object_size pathname, int flags, mode_t modes)
+ __overloadable
+ __clang_warning_if(!__open_modes_useful(flags) && modes,
+ "'open' " __open_useless_modes_warning) {
+ return __open_real(pathname, flags, modes);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int openat(int dirfd, const char* pathname, int flags, mode_t modes, ...)
+ __overloadable
+ __errorattr(__open_too_many_args_error);
+
+__BIONIC_FORTIFY_INLINE
+int openat(int dirfd, const char* const __pass_object_size pathname, int flags)
+ __overloadable
+ __clang_error_if(__open_modes_useful(flags), "'openat' " __open_too_few_args_error) {
+ return __openat_2(dirfd, pathname, flags);
+}
+
+__BIONIC_FORTIFY_INLINE
+int openat(int dirfd, const char* const __pass_object_size pathname, int flags, mode_t modes)
+ __overloadable
+ __clang_warning_if(!__open_modes_useful(flags) && modes,
+ "'openat' " __open_useless_modes_warning) {
+ return __openat_real(dirfd, pathname, flags, modes);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#else /* defined(__clang__) */
+__errordecl(__creat_missing_mode, __open_too_few_args_error);
+__errordecl(__creat_too_many_args, __open_too_many_args_error);
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+int open(const char* pathname, int flags, ...) {
+ if (__builtin_constant_p(flags)) {
+ if (__open_modes_useful(flags) && __builtin_va_arg_pack_len() == 0) {
+ __creat_missing_mode(); /* Compile time error. */
+ }
+ }
+
+ if (__builtin_va_arg_pack_len() > 1) {
+ __creat_too_many_args(); /* Compile time error. */
+ }
+
+ if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
+ return __open_2(pathname, flags);
+ }
+
+ return __open_real(pathname, flags, __builtin_va_arg_pack());
+}
+
+__BIONIC_FORTIFY_INLINE
+int openat(int dirfd, const char* pathname, int flags, ...) {
+ if (__builtin_constant_p(flags)) {
+ if (__open_modes_useful(flags) && __builtin_va_arg_pack_len() == 0) {
+ __creat_missing_mode(); /* Compile time error. */
+ }
+ }
+
+ if (__builtin_va_arg_pack_len() > 1) {
+ __creat_too_many_args(); /* Compile time error. */
+ }
+
+ if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
+ return __openat_2(dirfd, pathname, flags);
+ }
+
+ return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#endif /* defined(__clang__) */
+
+#undef __open_too_many_args_error
+#undef __open_too_few_args_error
+#undef __open_useless_modes_warning
+#undef __open_modes_useful
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/poll.h b/libc/include/bits/fortify/poll.h
new file mode 100644
index 0000000..8363e35
--- /dev/null
+++ b/libc/include/bits/fortify/poll.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _POLL_H_
+#error "Never include this file directly; instead, include <poll.h>"
+#endif
+
+int __poll_chk(struct pollfd*, nfds_t, int, size_t) __INTRODUCED_IN(23);
+int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t)
+ __INTRODUCED_IN(23);
+
+#if defined(__BIONIC_FORTIFY)
+#if __ANDROID_API__ >= __ANDROID_API_M__
+#if defined(__clang__)
+__BIONIC_FORTIFY_INLINE
+int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, int timeout)
+ __overloadable
+ __clang_error_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(fds) < sizeof(*fds) * fd_count,
+ "in call to 'poll', fd_count is larger than the given buffer") {
+ size_t bos_fds = __bos(fds);
+
+ if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(poll)(fds, fd_count, timeout);
+ }
+ return __poll_chk(fds, fd_count, timeout, bos_fds);
+}
+
+__BIONIC_FORTIFY_INLINE
+int ppoll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const struct timespec* timeout, const sigset_t* mask)
+ __overloadable
+ __clang_error_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(fds) < sizeof(*fds) * fd_count,
+ "in call to 'ppoll', fd_count is larger than the given buffer") {
+ size_t bos_fds = __bos(fds);
+
+ if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(ppoll)(fds, fd_count, timeout, mask);
+ }
+ return __ppoll_chk(fds, fd_count, timeout, mask, bos_fds);
+}
+#else /* defined(__clang__) */
+int __poll_real(struct pollfd*, nfds_t, int) __RENAME(poll);
+__errordecl(__poll_too_small_error, "poll: pollfd array smaller than fd count");
+
+int __ppoll_real(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __RENAME(ppoll)
+ __INTRODUCED_IN(21);
+__errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count");
+
+__BIONIC_FORTIFY_INLINE
+int poll(struct pollfd* fds, nfds_t fd_count, int timeout) {
+ if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ if (!__builtin_constant_p(fd_count)) {
+ return __poll_chk(fds, fd_count, timeout, __bos(fds));
+ } else if (__bos(fds) / sizeof(*fds) < fd_count) {
+ __poll_too_small_error();
+ }
+ }
+ return __poll_real(fds, fd_count, timeout);
+}
+
+__BIONIC_FORTIFY_INLINE
+int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout,
+ const sigset_t* mask) {
+ if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ if (!__builtin_constant_p(fd_count)) {
+ return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds));
+ } else if (__bos(fds) / sizeof(*fds) < fd_count) {
+ __ppoll_too_small_error();
+ }
+ }
+ return __ppoll_real(fds, fd_count, timeout, mask);
+}
+
+#endif /* defined(__clang__) */
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/socket.h b/libc/include/bits/fortify/socket.h
new file mode 100644
index 0000000..3e610d6
--- /dev/null
+++ b/libc/include/bits/fortify/socket.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYS_SOCKET_H_
+#error "Never include this file directly; instead, include <sys/socket.h>"
+#endif
+
+extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
+ socklen_t) __INTRODUCED_IN(26);
+ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
+ socklen_t*) __INTRODUCED_IN(21);
+
+#if defined(__BIONIC_FORTIFY)
+
+#define __recvfrom_bad_size "'recvfrom' called with size bigger than buffer"
+#define __sendto_bad_size "'sendto' called with size bigger than buffer"
+#if defined(__clang__)
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addr_len)
+ __overloadable
+ __clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos(buf) < len,
+ __recvfrom_bad_size) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr, addr_len);
+ }
+ return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
+__BIONIC_FORTIFY_INLINE
+ssize_t sendto(int fd, const void* const buf __pass_object_size0, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addr_len)
+ __overloadable
+ __clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
+ __sendto_bad_size) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(sendto)(fd, buf, len, flags, dest_addr, addr_len);
+ }
+ return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
+
+__BIONIC_FORTIFY_INLINE
+ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len, int flags)
+ __overloadable
+ __clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
+ "'recv' called with size bigger than buffer") {
+ return recvfrom(socket, buf, len, flags, NULL, 0);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t send(int socket, const void* const buf __pass_object_size0, size_t len, int flags)
+ __overloadable
+ __clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
+ "'send' called with size bigger than buffer") {
+ return sendto(socket, buf, len, flags, NULL, 0);
+}
+
+#else /* defined(__clang__) */
+ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
+__errordecl(__recvfrom_error, __recvfrom_bad_size);
+
+extern ssize_t __sendto_real(int, const void*, size_t, int, const struct sockaddr*, socklen_t)
+ __RENAME(sendto);
+__errordecl(__sendto_error, __sendto_bad_size);
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
+ struct sockaddr* src_addr, socklen_t* addr_len) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
+ }
+
+ if (__builtin_constant_p(len) && (len <= bos)) {
+ return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
+ }
+
+ if (__builtin_constant_p(len) && (len > bos)) {
+ __recvfrom_error();
+ }
+
+ return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
+__BIONIC_FORTIFY_INLINE
+ssize_t sendto(int fd, const void* buf, size_t len, int flags,
+ const struct sockaddr* dest_addr, socklen_t addr_len) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
+ }
+
+ if (__builtin_constant_p(len) && (len <= bos)) {
+ return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
+ }
+
+ if (__builtin_constant_p(len) && (len > bos)) {
+ __sendto_error();
+ }
+
+ return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
+
+__BIONIC_FORTIFY_INLINE
+ssize_t recv(int socket, void* buf, size_t len, int flags) {
+ return recvfrom(socket, buf, len, flags, NULL, 0);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t send(int socket, const void* buf, size_t len, int flags) {
+ return sendto(socket, buf, len, flags, NULL, 0);
+}
+#endif /* defined(__clang__) */
+
+#undef __recvfrom_bad_size
+#undef __sendto_bad_size
+#endif /* __BIONIC_FORTIFY */
diff --git a/libc/include/bits/fortify/stat.h b/libc/include/bits/fortify/stat.h
new file mode 100644
index 0000000..c168c38
--- /dev/null
+++ b/libc/include/bits/fortify/stat.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYS_STAT_H_
+#error "Never include this file directly; instead, include <sys/stat.h>"
+#endif
+
+mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
+
+#if defined(__BIONIC_FORTIFY)
+#define __umask_invalid_mode_str "'umask' called with invalid mode"
+
+#if defined(__clang__)
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
+/* Abuse enable_if to make this an overload of umask. */
+__BIONIC_FORTIFY_INLINE
+mode_t umask(mode_t mode)
+ __overloadable
+ __enable_if(1, "")
+ __clang_error_if(mode & ~0777, __umask_invalid_mode_str) {
+ return __umask_chk(mode);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#else /* defined(__clang__) */
+__errordecl(__umask_invalid_mode, __umask_invalid_mode_str);
+extern mode_t __umask_real(mode_t) __RENAME(umask);
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
+__BIONIC_FORTIFY_INLINE
+mode_t umask(mode_t mode) {
+ if (__builtin_constant_p(mode)) {
+ if ((mode & 0777) != mode) {
+ __umask_invalid_mode();
+ }
+ return __umask_real(mode);
+ }
+ return __umask_chk(mode);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#endif /* defined(__clang__) */
+#undef __umask_invalid_mode_str
+
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
new file mode 100644
index 0000000..cfc78d7
--- /dev/null
+++ b/libc/include/bits/fortify/stdio.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _STDIO_H_
+#error "Never include this file directly; instead, include <stdio.h>"
+#endif
+
+char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
+size_t __fread_chk(void*, size_t, size_t, FILE*, size_t) __INTRODUCED_IN(24);
+size_t __fwrite_chk(const void*, size_t, size_t, FILE*, size_t) __INTRODUCED_IN(24);
+
+#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE __printflike(3, 0)
+int vsnprintf(char* const __pass_object_size dest, size_t size, const char* format, va_list ap)
+ __overloadable {
+ return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
+}
+
+__BIONIC_FORTIFY_INLINE __printflike(2, 0)
+int vsprintf(char* const __pass_object_size dest, const char* format, va_list ap) __overloadable {
+ return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if defined(__clang__)
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+/*
+ * Simple case: `format` can't have format specifiers, so we can just compare
+ * its length to the length of `dest`
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int snprintf(char* dest, size_t size, const char* format)
+ __overloadable
+ __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(dest) < __builtin_strlen(format),
+ "format string will always overflow destination buffer")
+ __errorattr("format string will always overflow destination buffer");
+
+__BIONIC_FORTIFY_INLINE
+__printflike(3, 4)
+int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
+ __overloadable {
+ va_list va;
+ va_start(va, format);
+ int result = __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, va);
+ va_end(va);
+ return result;
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int sprintf(char* dest, const char* format)
+ __overloadable
+ __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(dest) < __builtin_strlen(format),
+ "format string will always overflow destination buffer")
+ __errorattr("format string will always overflow destination buffer");
+
+__BIONIC_FORTIFY_INLINE
+__printflike(2, 3)
+int sprintf(char* const __pass_object_size dest, const char* format, ...) __overloadable {
+ va_list va;
+ va_start(va, format);
+ int result = __builtin___vsprintf_chk(dest, 0, __bos(dest), format, va);
+ va_end(va);
+ return result;
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+size_t fread(void* const __pass_object_size0 buf, size_t size, size_t count, FILE* stream)
+ __overloadable
+ __clang_error_if(__unsafe_check_mul_overflow(size, count),
+ "in call to 'fread', size * count overflows")
+ __clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && size * count > __bos(buf),
+ "in call to 'fread', size * count is too large for the given buffer") {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(fread)(buf, size, count, stream);
+ }
+ return __fread_chk(buf, size, count, stream, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t fwrite(const void* const __pass_object_size0 buf, size_t size, size_t count, FILE* stream)
+ __overloadable
+ __clang_error_if(__unsafe_check_mul_overflow(size, count),
+ "in call to 'fwrite', size * count overflows")
+ __clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && size * count > __bos(buf),
+ "in call to 'fwrite', size * count is too large for the given buffer") {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
+ }
+
+ return __fwrite_chk(buf, size, count, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+char* fgets(char* const __pass_object_size dest, int size, FILE* stream)
+ __overloadable
+ __clang_error_if(size < 0, "in call to 'fgets', size should not be negative")
+ __clang_error_if(size > __bos(dest),
+ "in call to 'fgets', size is larger than the destination buffer") {
+ size_t bos = __bos(dest);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(fgets)(dest, size, stream);
+ }
+
+ return __fgets_chk(dest, size, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#else /* defined(__clang__) */
+
+size_t __fread_real(void*, size_t, size_t, FILE*) __RENAME(fread);
+__errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
+__errordecl(__fread_overflow, "fread called with overflowing size * count");
+
+char* __fgets_real(char*, int, FILE*) __RENAME(fgets);
+__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
+__errordecl(__fgets_too_small_error, "fgets called with size less than zero");
+
+size_t __fwrite_real(const void*, size_t, size_t, FILE*) __RENAME(fwrite);
+__errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer");
+__errordecl(__fwrite_overflow, "fwrite called with overflowing size * count");
+
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE __printflike(3, 4)
+int snprintf(char* dest, size_t size, const char* format, ...) {
+ return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format, __builtin_va_arg_pack());
+}
+
+__BIONIC_FORTIFY_INLINE __printflike(2, 3)
+int sprintf(char* dest, const char* format, ...) {
+ return __builtin___sprintf_chk(dest, 0, __bos(dest), format, __builtin_va_arg_pack());
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+size_t fread(void* buf, size_t size, size_t count, FILE* stream) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __fread_real(buf, size, count, stream);
+ }
+
+ if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
+ size_t total;
+ if (__size_mul_overflow(size, count, &total)) {
+ __fread_overflow();
+ }
+
+ if (total > bos) {
+ __fread_too_big_error();
+ }
+
+ return __fread_real(buf, size, count, stream);
+ }
+
+ return __fread_chk(buf, size, count, stream, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t fwrite(const void* buf, size_t size, size_t count, FILE* stream) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __fwrite_real(buf, size, count, stream);
+ }
+
+ if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
+ size_t total;
+ if (__size_mul_overflow(size, count, &total)) {
+ __fwrite_overflow();
+ }
+
+ if (total > bos) {
+ __fwrite_too_big_error();
+ }
+
+ return __fwrite_real(buf, size, count, stream);
+ }
+
+ return __fwrite_chk(buf, size, count, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+char *fgets(char* dest, int size, FILE* stream) {
+ size_t bos = __bos(dest);
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always negative. Force a compiler error.
+ if (__builtin_constant_p(size) && (size < 0)) {
+ __fgets_too_small_error();
+ }
+
+ // Compiler doesn't know destination size. Don't call __fgets_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __fgets_real(dest, size, stream);
+ }
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always <= the actual object size. Don't call __fgets_chk
+ if (__builtin_constant_p(size) && (size <= (int) bos)) {
+ return __fgets_real(dest, size, stream);
+ }
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always > the actual object size. Force a compiler error.
+ if (__builtin_constant_p(size) && (size > (int) bos)) {
+ __fgets_too_big_error();
+ }
+
+ return __fgets_chk(dest, size, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#endif /* defined(__clang__) */
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h
new file mode 100644
index 0000000..8f3b02c
--- /dev/null
+++ b/libc/include/bits/fortify/stdlib.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _STDLIB_H
+#error "Never include this file directly; instead, include <stdlib.h>"
+#endif
+
+#if defined(__BIONIC_FORTIFY)
+#define __realpath_buf_too_small_str \
+ "'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes"
+
+/* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
+#define __PATH_MAX 4096
+
+#if defined(__clang__)
+char* realpath(const char* path, char* resolved)
+ __clang_error_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(resolved) < __PATH_MAX, __realpath_buf_too_small_str)
+ __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?");
+/* No need for a definition; the only issues we can catch are at compile-time. */
+
+#else /* defined(__clang__) */
+
+char* __realpath_real(const char*, char*) __RENAME(realpath);
+__errordecl(__realpath_size_error, __realpath_buf_too_small_str);
+
+__BIONIC_FORTIFY_INLINE
+char* realpath(const char* path, char* resolved) {
+ size_t bos = __bos(resolved);
+
+ if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) {
+ __realpath_size_error();
+ }
+
+ return __realpath_real(path, resolved);
+}
+
+#endif /* defined(__clang__) */
+
+#undef __PATH_MAX
+#undef __realpath_buf_too_small_str
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
new file mode 100644
index 0000000..f994e3e
--- /dev/null
+++ b/libc/include/bits/fortify/string.h
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _STRING_H
+#error "Never include this file directly; instead, include <string.h>"
+#endif
+
+void* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
+void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
+char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
+char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
+size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
+size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
+
+#if defined(__BIONIC_FORTIFY)
+extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
+
+// These can share their implementation between gcc and clang with minimal
+// trickery...
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+ __overloadable
+ __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < copy_amount,
+ "'memcpy' called with size bigger than buffer") {
+ return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
+ __overloadable
+ __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < len,
+ "'memmove' called with size bigger than buffer") {
+ return __builtin___memmove_chk(dst, src, len, __bos0(dst));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+char* stpcpy(char* const dst __pass_object_size, const char* src)
+ __overloadable
+ __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(dst) <= __builtin_strlen(src),
+ "'stpcpy' called with string bigger than buffer") {
+ return __builtin___stpcpy_chk(dst, src, __bos(dst));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+char* strcpy(char* const dst __pass_object_size, const char* src)
+ __overloadable
+ __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(dst) <= __builtin_strlen(src),
+ "'strcpy' called with string bigger than buffer") {
+ return __builtin___strcpy_chk(dst, src, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strcat(char* const dst __pass_object_size, const char* src) __overloadable {
+ return __builtin___strcat_chk(dst, src, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
+ return __builtin___strncat_chk(dst, src, n, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memset(void* const s __pass_object_size0, int c, size_t n)
+ __overloadable
+ __clang_error_if(__bos0(s) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(s) < n,
+ "'memset' called with size bigger than buffer")
+ /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
+ __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
+ return __builtin___memset_chk(s, c, n, __bos0(s));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+
+#if defined(__clang__)
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_memchr(s, c, n);
+ }
+
+ return __memchr_chk(s, c, n, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __memrchr_real(s, c, n);
+ }
+
+ return __memrchr_chk(s, c, n, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+ __overloadable {
+ size_t bos_dst = __bos(dst);
+ size_t bos_src = __bos(src);
+
+ /* Ignore dst size checks; they're handled in strncpy_chk */
+ if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+ }
+
+ return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+ __overloadable {
+ size_t bos_dst = __bos(dst);
+ size_t bos_src = __bos(src);
+
+ /* Ignore dst size checks; they're handled in strncpy_chk */
+ if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin___strncpy_chk(dst, src, n, bos_dst);
+ }
+
+ return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
+ size_t bos = __bos(dst);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(strlcpy)(dst, src, size);
+ }
+
+ return __strlcpy_chk(dst, src, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
+ size_t bos = __bos(dst);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(strlcat)(dst, src, size);
+ }
+
+ return __strlcat_chk(dst, src, size, bos);
+}
+
+/*
+ * If we can evaluate the size of s at compile-time, just call __builtin_strlen
+ * on it directly. This makes it way easier for compilers to fold things like
+ * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
+ * because it's large.
+ */
+__BIONIC_FORTIFY_INLINE
+size_t strlen(const char* const s __pass_object_size)
+ __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
+ "enabled if s is a known good string.") {
+ return __builtin_strlen(s);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlen(const char* const s __pass_object_size0) __overloadable {
+ size_t bos = __bos0(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strlen(s);
+ }
+
+ return __strlen_chk(s, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
+__BIONIC_FORTIFY_INLINE
+char* strchr(const char* const s __pass_object_size, int c) __overloadable {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strchr(s, c);
+ }
+
+ return __strchr_chk(s, c, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strrchr(s, c);
+ }
+
+ return __strrchr_chk(s, c, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#else // defined(__clang__)
+extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
+extern size_t __strlcpy_real(char*, const char*, size_t)
+ __RENAME(strlcpy);
+extern size_t __strlcat_real(char*, const char*, size_t)
+ __RENAME(strlcat);
+
+__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
+__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+void* memchr(const void* s __pass_object_size, int c, size_t n) {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_memchr(s, c, n);
+ }
+
+ if (__builtin_constant_p(n) && (n > bos)) {
+ __memchr_buf_size_error();
+ }
+
+ if (__builtin_constant_p(n) && (n <= bos)) {
+ return __builtin_memchr(s, c, n);
+ }
+
+ return __memchr_chk(s, c, n, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+void* __memrchr_fortify(const void* s, int c, size_t n) {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __memrchr_real(s, c, n);
+ }
+
+ if (__builtin_constant_p(n) && (n > bos)) {
+ __memrchr_buf_size_error();
+ }
+
+ if (__builtin_constant_p(n) && (n <= bos)) {
+ return __memrchr_real(s, c, n);
+ }
+
+ return __memrchr_chk(s, c, n, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+char* stpncpy(char* dst, const char* src, size_t n) {
+ size_t bos_dst = __bos(dst);
+ size_t bos_src = __bos(src);
+
+ if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+ }
+
+ if (__builtin_constant_p(n) && (n <= bos_src)) {
+ return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+ }
+
+ size_t slen = __builtin_strlen(src);
+ if (__builtin_constant_p(slen)) {
+ return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+ }
+
+ return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strncpy(char* dst, const char* src, size_t n) {
+ size_t bos_dst = __bos(dst);
+ size_t bos_src = __bos(src);
+
+ if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __strncpy_real(dst, src, n);
+ }
+
+ if (__builtin_constant_p(n) && (n <= bos_src)) {
+ return __builtin___strncpy_chk(dst, src, n, bos_dst);
+ }
+
+ size_t slen = __builtin_strlen(src);
+ if (__builtin_constant_p(slen)) {
+ return __builtin___strncpy_chk(dst, src, n, bos_dst);
+ }
+
+ return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+size_t strlcpy(char* dst __pass_object_size, const char* src, size_t size) {
+ size_t bos = __bos(dst);
+
+ // Compiler doesn't know destination size. Don't call __strlcpy_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __strlcpy_real(dst, src, size);
+ }
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always <= the actual object size. Don't call __strlcpy_chk
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __strlcpy_real(dst, src, size);
+ }
+
+ return __strlcpy_chk(dst, src, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlcat(char* dst, const char* src, size_t size) {
+ size_t bos = __bos(dst);
+
+ // Compiler doesn't know destination size. Don't call __strlcat_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __strlcat_real(dst, src, size);
+ }
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always <= the actual object size. Don't call __strlcat_chk
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __strlcat_real(dst, src, size);
+ }
+
+ return __strlcat_chk(dst, src, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlen(const char* s) __overloadable {
+ size_t bos = __bos(s);
+
+ // Compiler doesn't know destination size. Don't call __strlen_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strlen(s);
+ }
+
+ size_t slen = __builtin_strlen(s);
+ if (__builtin_constant_p(slen)) {
+ return slen;
+ }
+
+ return __strlen_chk(s, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
+__BIONIC_FORTIFY_INLINE
+char* strchr(const char* s, int c) {
+ size_t bos = __bos(s);
+
+ // Compiler doesn't know destination size. Don't call __strchr_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strchr(s, c);
+ }
+
+ size_t slen = __builtin_strlen(s);
+ if (__builtin_constant_p(slen) && (slen < bos)) {
+ return __builtin_strchr(s, c);
+ }
+
+ return __strchr_chk(s, c, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strrchr(const char* s, int c) {
+ size_t bos = __bos(s);
+
+ // Compiler doesn't know destination size. Don't call __strrchr_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strrchr(s, c);
+ }
+
+ size_t slen = __builtin_strlen(s);
+ if (__builtin_constant_p(slen) && (slen < bos)) {
+ return __builtin_strrchr(s, c);
+ }
+
+ return __strrchr_chk(s, c, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+#endif /* defined(__clang__) */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+#if defined(__cplusplus)
+extern "C++" {
+__BIONIC_FORTIFY_INLINE
+void* memrchr(void* const __pass_object_size s, int c, size_t n) {
+ return __memrchr_fortify(s, c, n);
+}
+
+__BIONIC_FORTIFY_INLINE
+const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
+ return __memrchr_fortify(s, c, n);
+}
+}
+#else
+__BIONIC_FORTIFY_INLINE
+void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
+ return __memrchr_fortify(s, c, n);
+}
+#endif
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h
new file mode 100644
index 0000000..ea5c89d
--- /dev/null
+++ b/libc/include/bits/fortify/unistd.h
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _UNISTD_H_
+#error "Never include this file directly; instead, include <unistd.h>"
+#endif
+
+char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
+
+ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
+ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
+
+ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
+ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12);
+
+ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
+ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
+
+ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
+ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64)
+ __INTRODUCED_IN(12);
+
+ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
+ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
+ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
+ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
+
+#if defined(__BIONIC_FORTIFY)
+
+#if defined(__USE_FILE_OFFSET64)
+#define __PREAD_PREFIX(x) __pread64_ ## x
+#define __PWRITE_PREFIX(x) __pwrite64_ ## x
+#else
+#define __PREAD_PREFIX(x) __pread_ ## x
+#define __PWRITE_PREFIX(x) __pwrite_ ## x
+#endif
+
+#if defined(__clang__)
+#define __error_if_overflows_ssizet(what, fn) \
+ __clang_error_if((what) > SSIZE_MAX, "in call to '" #fn "', '" #what "' must be <= SSIZE_MAX")
+
+#define __error_if_overflows_objectsize(what, objsize, fn) \
+ __clang_error_if((objsize) != __BIONIC_FORTIFY_UNKNOWN_SIZE && (what) > (objsize), \
+ "in call to '" #fn "', '" #what "' bytes overflows the given object")
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+char* getcwd(char* const __pass_object_size buf, size_t size)
+ __overloadable
+ __error_if_overflows_objectsize(size, __bos(buf), getcwd) {
+ size_t bos = __bos(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(getcwd)(buf, size);
+ }
+
+ return __getcwd_chk(buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count, off_t offset)
+ __overloadable
+ __error_if_overflows_ssizet(count, pread)
+ __error_if_overflows_objectsize(count, __bos0(buf), pread) {
+ size_t bos = __bos0(buf);
+
+ if (count == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __PREAD_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count, off64_t offset)
+ __overloadable
+ __error_if_overflows_ssizet(count, pread64)
+ __error_if_overflows_objectsize(count, __bos0(buf), pread64) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __pread64_real(fd, buf, count, offset);
+ }
+
+ return __pread64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count, off_t offset)
+ __overloadable
+ __error_if_overflows_ssizet(count, pwrite)
+ __error_if_overflows_objectsize(count, __bos0(buf), pwrite) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf, size_t count, off64_t offset)
+ __overloadable
+ __error_if_overflows_ssizet(count, pwrite64)
+ __error_if_overflows_objectsize(count, __bos0(buf), pwrite64) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __pwrite64_real(fd, buf, count, offset);
+ }
+
+ return __pwrite64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
+ __overloadable
+ __error_if_overflows_ssizet(count, read)
+ __error_if_overflows_objectsize(count, __bos0(buf), read) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(read)(fd, buf, count);
+ }
+
+ return __read_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
+ __overloadable
+ __error_if_overflows_ssizet(count, write)
+ __error_if_overflows_objectsize(count, __bos0(buf), write) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(write)(fd, buf, count);
+ }
+
+ return __write_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+ssize_t readlink(const char* path, char* const __pass_object_size buf, size_t size)
+ __overloadable
+ __error_if_overflows_ssizet(size, readlink)
+ __error_if_overflows_objectsize(size, __bos(buf), readlink) {
+ size_t bos = __bos(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(readlink)(path, buf, size);
+ }
+
+ return __readlink_chk(path, buf, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t readlinkat(int dirfd, const char* path, char* const __pass_object_size buf, size_t size)
+ __overloadable
+ __error_if_overflows_ssizet(size, readlinkat)
+ __error_if_overflows_objectsize(size, __bos(buf), readlinkat) {
+ size_t bos = __bos(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(readlinkat)(dirfd, path, buf, size);
+ }
+
+ return __readlinkat_chk(dirfd, path, buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#undef __enable_if_no_overflow_ssizet
+#undef __error_if_overflows_objectsize
+#undef __error_if_overflows_ssizet
+#else /* defined(__clang__) */
+
+char* __getcwd_real(char*, size_t) __RENAME(getcwd);
+ssize_t __read_real(int, void*, size_t) __RENAME(read);
+ssize_t __write_real(int, const void*, size_t) __RENAME(write);
+ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);
+ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat);
+
+__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination");
+__errordecl(__pread_dest_size_error, "pread called with size bigger than destination");
+__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX");
+__errordecl(__pread64_dest_size_error, "pread64 called with size bigger than destination");
+__errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX");
+__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination");
+__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX");
+__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination");
+__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX");
+__errordecl(__read_dest_size_error, "read called with size bigger than destination");
+__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX");
+__errordecl(__write_dest_size_error, "write called with size bigger than destination");
+__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX");
+__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination");
+__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX");
+__errordecl(__readlinkat_dest_size_error, "readlinkat called with size bigger than destination");
+__errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX");
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+char* getcwd(char* buf, size_t size) __overloadable {
+ size_t bos = __bos(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __getcwd_real(buf, size);
+ }
+
+ if (__builtin_constant_p(size) && (size > bos)) {
+ __getcwd_dest_size_error();
+ }
+
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __getcwd_real(buf, size);
+ }
+
+ return __getcwd_chk(buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __PREAD_PREFIX(count_toobig_error)();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __PREAD_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __PREAD_PREFIX(dest_size_error)();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __PREAD_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __pread64_count_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __pread64_real(fd, buf, count, offset);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __pread64_dest_size_error();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __pread64_real(fd, buf, count, offset);
+ }
+
+ return __pread64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __PWRITE_PREFIX(count_toobig_error)();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __PWRITE_PREFIX(dest_size_error)();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __pwrite64_count_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __pwrite64_real(fd, buf, count, offset);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __pwrite64_dest_size_error();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __pwrite64_real(fd, buf, count, offset);
+ }
+
+ return __pwrite64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+ssize_t read(int fd, void* buf, size_t count) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __read_count_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __read_real(fd, buf, count);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __read_dest_size_error();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __read_real(fd, buf, count);
+ }
+
+ return __read_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t write(int fd, const void* buf, size_t count) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __write_real(fd, buf, count);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __write_dest_size_error();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __write_real(fd, buf, count);
+ }
+
+ return __write_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+ssize_t readlink(const char* path, char* buf, size_t size) {
+ size_t bos = __bos(buf);
+
+ if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
+ __readlink_size_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __readlink_real(path, buf, size);
+ }
+
+ if (__builtin_constant_p(size) && (size > bos)) {
+ __readlink_dest_size_error();
+ }
+
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __readlink_real(path, buf, size);
+ }
+
+ return __readlink_chk(path, buf, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {
+ size_t bos = __bos(buf);
+
+ if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
+ __readlinkat_size_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __readlinkat_real(dirfd, path, buf, size);
+ }
+
+ if (__builtin_constant_p(size) && (size > bos)) {
+ __readlinkat_dest_size_error();
+ }
+
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __readlinkat_real(dirfd, path, buf, size);
+ }
+
+ return __readlinkat_chk(dirfd, path, buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+#endif /* defined(__clang__) */
+#undef __PREAD_PREFIX
+#undef __PWRITE_PREFIX
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/getopt.h b/libc/include/bits/getopt.h
index 7153d48..5481449 100644
--- a/libc/include/bits/getopt.h
+++ b/libc/include/bits/getopt.h
@@ -33,9 +33,9 @@
__BEGIN_DECLS
-int getopt(int, char * const [], const char *);
+int getopt(int __argc, char* const __argv[], const char* __options);
-extern char *optarg; /* getopt(3) external variables */
+extern char* optarg;
extern int optind, opterr, optopt;
__END_DECLS
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index 3191a23..f08c614 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -1,6 +1,15 @@
/* Generated by gensyscalls.py. Do not edit. */
#ifndef _BIONIC_BITS_GLIBC_SYSCALLS_H_
#define _BIONIC_BITS_GLIBC_SYSCALLS_H_
+#if defined(__NR__llseek)
+ #define SYS__llseek __NR__llseek
+#endif
+#if defined(__NR__newselect)
+ #define SYS__newselect __NR__newselect
+#endif
+#if defined(__NR__sysctl)
+ #define SYS__sysctl __NR__sysctl
+#endif
#if defined(__NR_accept)
#define SYS_accept __NR_accept
#endif
@@ -1063,6 +1072,9 @@
#if defined(__NR_statfs64)
#define SYS_statfs64 __NR_statfs64
#endif
+#if defined(__NR_statx)
+ #define SYS_statx __NR_statx
+#endif
#if defined(__NR_stime)
#define SYS_stime __NR_stime
#endif
diff --git a/libc/include/bits/ioctl.h b/libc/include/bits/ioctl.h
index 53116ca..0cf87d2 100644
--- a/libc/include/bits/ioctl.h
+++ b/libc/include/bits/ioctl.h
@@ -33,7 +33,7 @@
__BEGIN_DECLS
-int ioctl(int, int, ...);
+int ioctl(int __fd, int __request, ...);
__END_DECLS
diff --git a/libc/include/bits/lockf.h b/libc/include/bits/lockf.h
index c24f18b..929c68c 100644
--- a/libc/include/bits/lockf.h
+++ b/libc/include/bits/lockf.h
@@ -39,12 +39,8 @@
__BEGIN_DECLS
-#if defined(__USE_FILE_OFFSET64)
-int lockf(int, int, off_t) __RENAME(lockf64) __INTRODUCED_IN(24);
-#else
-int lockf(int, int, off_t) __INTRODUCED_IN(24);
-#endif
-int lockf64(int, int, off64_t) __INTRODUCED_IN(24);
+int lockf(int __fd, int __cmd, off_t __length) __RENAME_IF_FILE_OFFSET64(lockf64) __INTRODUCED_IN(24);
+int lockf64(int __fd, int __cmd, off64_t __length) __INTRODUCED_IN(24);
__END_DECLS
diff --git a/libc/include/bits/strcasecmp.h b/libc/include/bits/strcasecmp.h
index df1a6b8..594046a 100644
--- a/libc/include/bits/strcasecmp.h
+++ b/libc/include/bits/strcasecmp.h
@@ -35,10 +35,10 @@
__BEGIN_DECLS
-int strcasecmp(const char*, const char*) __attribute_pure__;
-int strcasecmp_l(const char*, const char*, locale_t) __attribute_pure__ __INTRODUCED_IN(23);
-int strncasecmp(const char*, const char*, size_t) __attribute_pure__;
-int strncasecmp_l(const char*, const char*, size_t, locale_t) __attribute_pure__ __INTRODUCED_IN(23);
+int strcasecmp(const char* __s1, const char* __s2) __attribute_pure__;
+int strcasecmp_l(const char* __s1, const char* __s2, locale_t __l) __attribute_pure__ __INTRODUCED_IN(23);
+int strncasecmp(const char* __s1, const char* __s2, size_t __n) __attribute_pure__;
+int strncasecmp_l(const char* __s1, const char* __s2, size_t __n, locale_t __l) __attribute_pure__ __INTRODUCED_IN(23);
__END_DECLS
diff --git a/libc/include/bits/wctype.h b/libc/include/bits/wctype.h
index f21d46e..a51eca2 100644
--- a/libc/include/bits/wctype.h
+++ b/libc/include/bits/wctype.h
@@ -37,29 +37,29 @@
#define WEOF __BIONIC_CAST(static_cast, wint_t, -1)
-int iswalnum(wint_t);
-int iswalpha(wint_t);
-int iswblank(wint_t) __INTRODUCED_IN(21);
-int iswcntrl(wint_t);
-int iswdigit(wint_t);
-int iswgraph(wint_t);
-int iswlower(wint_t);
-int iswprint(wint_t);
-int iswpunct(wint_t);
-int iswspace(wint_t);
-int iswupper(wint_t);
-int iswxdigit(wint_t);
+int iswalnum(wint_t __wc);
+int iswalpha(wint_t __wc);
+int iswblank(wint_t __wc) __INTRODUCED_IN(21);
+int iswcntrl(wint_t __wc);
+int iswdigit(wint_t __wc);
+int iswgraph(wint_t __wc);
+int iswlower(wint_t __wc);
+int iswprint(wint_t __wc);
+int iswpunct(wint_t __wc);
+int iswspace(wint_t __wc);
+int iswupper(wint_t __wc);
+int iswxdigit(wint_t __wc);
-wint_t towlower(wint_t);
-wint_t towupper(wint_t);
+wint_t towlower(wint_t __wc);
+wint_t towupper(wint_t __wc);
typedef long wctype_t;
-wctype_t wctype(const char*);
-int iswctype(wint_t, wctype_t);
+wctype_t wctype(const char* __name);
+int iswctype(wint_t __wc, wctype_t __type);
typedef const void* wctrans_t;
-wint_t towctrans(wint_t, wctrans_t) __INTRODUCED_IN(26) __VERSIONER_NO_GUARD;
-wctrans_t wctrans(const char*) __INTRODUCED_IN(26) __VERSIONER_NO_GUARD;
+wint_t towctrans(wint_t __wc, wctrans_t __transform) __INTRODUCED_IN(26) __VERSIONER_NO_GUARD;
+wctrans_t wctrans(const char* __name) __INTRODUCED_IN(26) __VERSIONER_NO_GUARD;
__END_DECLS
diff --git a/libc/include/complex.h b/libc/include/complex.h
index c020e4f..79fe07c 100644
--- a/libc/include/complex.h
+++ b/libc/include/complex.h
@@ -59,102 +59,102 @@
/* 7.3.5 Trigonometric functions */
/* 7.3.5.1 The cacos functions */
-double complex cacos(double complex) __INTRODUCED_IN(23);
-float complex cacosf(float complex) __INTRODUCED_IN(23);
-long double complex cacosl(long double complex) __INTRODUCED_IN(26);
+double complex cacos(double complex __z) __INTRODUCED_IN(23);
+float complex cacosf(float complex __z) __INTRODUCED_IN(23);
+long double complex cacosl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.2 The casin functions */
-double complex casin(double complex) __INTRODUCED_IN(23);
-float complex casinf(float complex) __INTRODUCED_IN(23);
-long double complex casinl(long double complex) __INTRODUCED_IN(26);
+double complex casin(double complex __z) __INTRODUCED_IN(23);
+float complex casinf(float complex __z) __INTRODUCED_IN(23);
+long double complex casinl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.1 The catan functions */
-double complex catan(double complex) __INTRODUCED_IN(23);
-float complex catanf(float complex) __INTRODUCED_IN(23);
-long double complex catanl(long double complex) __INTRODUCED_IN(26);
+double complex catan(double complex __z) __INTRODUCED_IN(23);
+float complex catanf(float complex __z) __INTRODUCED_IN(23);
+long double complex catanl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.1 The ccos functions */
-double complex ccos(double complex) __INTRODUCED_IN(23);
-float complex ccosf(float complex) __INTRODUCED_IN(23);
-long double complex ccosl(long double complex) __INTRODUCED_IN(26);
+double complex ccos(double complex __z) __INTRODUCED_IN(23);
+float complex ccosf(float complex __z) __INTRODUCED_IN(23);
+long double complex ccosl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.1 The csin functions */
-double complex csin(double complex) __INTRODUCED_IN(23);
-float complex csinf(float complex) __INTRODUCED_IN(23);
-long double complex csinl(long double complex) __INTRODUCED_IN(26);
+double complex csin(double complex __z) __INTRODUCED_IN(23);
+float complex csinf(float complex __z) __INTRODUCED_IN(23);
+long double complex csinl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.5.1 The ctan functions */
-double complex ctan(double complex) __INTRODUCED_IN(23);
-float complex ctanf(float complex) __INTRODUCED_IN(23);
-long double complex ctanl(long double complex) __INTRODUCED_IN(26);
+double complex ctan(double complex __z) __INTRODUCED_IN(23);
+float complex ctanf(float complex __z) __INTRODUCED_IN(23);
+long double complex ctanl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6 Hyperbolic functions */
/* 7.3.6.1 The cacosh functions */
-double complex cacosh(double complex) __INTRODUCED_IN(23);
-float complex cacoshf(float complex) __INTRODUCED_IN(23);
-long double complex cacoshl(long double complex) __INTRODUCED_IN(26);
+double complex cacosh(double complex __z) __INTRODUCED_IN(23);
+float complex cacoshf(float complex __z) __INTRODUCED_IN(23);
+long double complex cacoshl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.2 The casinh functions */
-double complex casinh(double complex) __INTRODUCED_IN(23);
-float complex casinhf(float complex) __INTRODUCED_IN(23);
-long double complex casinhl(long double complex) __INTRODUCED_IN(26);
+double complex casinh(double complex __z) __INTRODUCED_IN(23);
+float complex casinhf(float complex __z) __INTRODUCED_IN(23);
+long double complex casinhl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.3 The catanh functions */
-double complex catanh(double complex) __INTRODUCED_IN(23);
-float complex catanhf(float complex) __INTRODUCED_IN(23);
-long double complex catanhl(long double complex) __INTRODUCED_IN(26);
+double complex catanh(double complex __z) __INTRODUCED_IN(23);
+float complex catanhf(float complex __z) __INTRODUCED_IN(23);
+long double complex catanhl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.4 The ccosh functions */
-double complex ccosh(double complex) __INTRODUCED_IN(23);
-float complex ccoshf(float complex) __INTRODUCED_IN(23);
-long double complex ccoshl(long double complex) __INTRODUCED_IN(26);
+double complex ccosh(double complex __z) __INTRODUCED_IN(23);
+float complex ccoshf(float complex __z) __INTRODUCED_IN(23);
+long double complex ccoshl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.5 The csinh functions */
-double complex csinh(double complex) __INTRODUCED_IN(23);
-float complex csinhf(float complex) __INTRODUCED_IN(23);
-long double complex csinhl(long double complex) __INTRODUCED_IN(26);
+double complex csinh(double complex __z) __INTRODUCED_IN(23);
+float complex csinhf(float complex __z) __INTRODUCED_IN(23);
+long double complex csinhl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.6.6 The ctanh functions */
-double complex ctanh(double complex) __INTRODUCED_IN(23);
-float complex ctanhf(float complex) __INTRODUCED_IN(23);
-long double complex ctanhl(long double complex) __INTRODUCED_IN(26);
+double complex ctanh(double complex __z) __INTRODUCED_IN(23);
+float complex ctanhf(float complex __z) __INTRODUCED_IN(23);
+long double complex ctanhl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.7 Exponential and logarithmic functions */
/* 7.3.7.1 The cexp functions */
-double complex cexp(double complex) __INTRODUCED_IN(23);
-float complex cexpf(float complex) __INTRODUCED_IN(23);
-long double complex cexpl(long double complex) __INTRODUCED_IN(26);
+double complex cexp(double complex __z) __INTRODUCED_IN(23);
+float complex cexpf(float complex __z) __INTRODUCED_IN(23);
+long double complex cexpl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.7.2 The clog functions */
-double complex clog(double complex) __INTRODUCED_IN(26);
-float complex clogf(float complex) __INTRODUCED_IN(26);
-long double complex clogl(long double complex) __INTRODUCED_IN(26);
+double complex clog(double complex __z) __INTRODUCED_IN(26);
+float complex clogf(float complex __z) __INTRODUCED_IN(26);
+long double complex clogl(long double complex __z) __INTRODUCED_IN(26);
/* 7.3.8 Power and absolute-value functions */
/* 7.3.8.1 The cabs functions */
-double cabs(double complex) __INTRODUCED_IN(23);
-float cabsf(float complex) __INTRODUCED_IN(23);
-long double cabsl(long double complex) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
+double cabs(double complex __z) __INTRODUCED_IN(23);
+float cabsf(float complex __z) __INTRODUCED_IN(23);
+long double cabsl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
/* 7.3.8.2 The cpow functions */
-double complex cpow(double complex, double complex) __INTRODUCED_IN(26);
-float complex cpowf(float complex, float complex) __INTRODUCED_IN(26);
-long double complex cpowl(long double complex, long double complex) __INTRODUCED_IN(26);
+double complex cpow(double complex __x, double complex __z) __INTRODUCED_IN(26);
+float complex cpowf(float complex __x, float complex __z) __INTRODUCED_IN(26);
+long double complex cpowl(long double complex __x, long double complex __z) __INTRODUCED_IN(26);
/* 7.3.8.3 The csqrt functions */
-double complex csqrt(double complex) __INTRODUCED_IN(23);
-float complex csqrtf(float complex) __INTRODUCED_IN(23);
-long double complex csqrtl(long double complex) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
+double complex csqrt(double complex __z) __INTRODUCED_IN(23);
+float complex csqrtf(float complex __z) __INTRODUCED_IN(23);
+long double complex csqrtl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
/* 7.3.9 Manipulation functions */
/* 7.3.9.1 The carg functions */
-double carg(double complex) __INTRODUCED_IN(23);
-float cargf(float complex) __INTRODUCED_IN(23);
-long double cargl(long double complex) __INTRODUCED_IN(23);
+double carg(double complex __z) __INTRODUCED_IN(23);
+float cargf(float complex __z) __INTRODUCED_IN(23);
+long double cargl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9.2 The cimag functions */
-double cimag(double complex) __INTRODUCED_IN(23);
-float cimagf(float complex) __INTRODUCED_IN(23);
-long double cimagl(long double complex) __INTRODUCED_IN(23);
+double cimag(double complex __z) __INTRODUCED_IN(23);
+float cimagf(float complex __z) __INTRODUCED_IN(23);
+long double cimagl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9.3 The conj functions */
-double complex conj(double complex) __INTRODUCED_IN(23);
-float complex conjf(float complex) __INTRODUCED_IN(23);
-long double complex conjl(long double complex) __INTRODUCED_IN(23);
+double complex conj(double complex __z) __INTRODUCED_IN(23);
+float complex conjf(float complex __z) __INTRODUCED_IN(23);
+long double complex conjl(long double complex __z) __INTRODUCED_IN(23);
/* 7.3.9.4 The cproj functions */
-double complex cproj(double complex) __INTRODUCED_IN(23);
-float complex cprojf(float complex) __INTRODUCED_IN(23);
-long double complex cprojl(long double complex) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
+double complex cproj(double complex __z) __INTRODUCED_IN(23);
+float complex cprojf(float complex __z) __INTRODUCED_IN(23);
+long double complex cprojl(long double complex __z) __INTRODUCED_IN_32(21) __INTRODUCED_IN_64(23);
/* 7.3.9.5 The creal functions */
-double creal(double complex) __INTRODUCED_IN(23);
-float crealf(float complex) __INTRODUCED_IN(23);
-long double creall(long double complex) __INTRODUCED_IN(23);
+double creal(double complex __z) __INTRODUCED_IN(23);
+float crealf(float complex __z) __INTRODUCED_IN(23);
+long double creall(long double complex __z) __INTRODUCED_IN(23);
__END_DECLS
-#endif /* _COMPLEX_H */
+#endif
diff --git a/libc/include/ctype.h b/libc/include/ctype.h
index 84dd5aa..df11cb1 100644
--- a/libc/include/ctype.h
+++ b/libc/include/ctype.h
@@ -61,45 +61,45 @@
extern const char* _ctype_;
-int isalnum(int);
-int isalpha(int);
-int isblank(int);
-int iscntrl(int);
-int isdigit(int);
-int isgraph(int);
-int islower(int);
-int isprint(int);
-int ispunct(int);
-int isspace(int);
-int isupper(int);
-int isxdigit(int);
-int tolower(int);
-int toupper(int);
+int isalnum(int __ch);
+int isalpha(int __ch);
+int isblank(int __ch);
+int iscntrl(int __ch);
+int isdigit(int __ch);
+int isgraph(int __ch);
+int islower(int __ch);
+int isprint(int __ch);
+int ispunct(int __ch);
+int isspace(int __ch);
+int isupper(int __ch);
+int isxdigit(int __ch);
+int tolower(int __ch);
+int toupper(int __ch);
#if __ANDROID_API__ >= __ANDROID_API_L__
-int isalnum_l(int, locale_t) __INTRODUCED_IN(21);
-int isalpha_l(int, locale_t) __INTRODUCED_IN(21);
-int isblank_l(int, locale_t) __INTRODUCED_IN(21);
-int iscntrl_l(int, locale_t) __INTRODUCED_IN(21);
-int isdigit_l(int, locale_t) __INTRODUCED_IN(21);
-int isgraph_l(int, locale_t) __INTRODUCED_IN(21);
-int islower_l(int, locale_t) __INTRODUCED_IN(21);
-int isprint_l(int, locale_t) __INTRODUCED_IN(21);
-int ispunct_l(int, locale_t) __INTRODUCED_IN(21);
-int isspace_l(int, locale_t) __INTRODUCED_IN(21);
-int isupper_l(int, locale_t) __INTRODUCED_IN(21);
-int isxdigit_l(int, locale_t) __INTRODUCED_IN(21);
-int tolower_l(int, locale_t) __INTRODUCED_IN(21);
-int toupper_l(int, locale_t) __INTRODUCED_IN(21);
+int isalnum_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isalpha_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isblank_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int iscntrl_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isdigit_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isgraph_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int islower_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isprint_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int ispunct_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isspace_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isupper_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int isxdigit_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int tolower_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
+int toupper_l(int __ch, locale_t __l) __INTRODUCED_IN(21);
#else
// Implemented as static inlines before 21.
#endif
-int isascii(int);
-int toascii(int);
-int _tolower(int) __INTRODUCED_IN(21);
-int _toupper(int) __INTRODUCED_IN(21);
+int isascii(int __ch);
+int toascii(int __ch);
+int _tolower(int __ch) __INTRODUCED_IN(21);
+int _toupper(int __ch) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* !_CTYPE_H_ */
+#endif
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index ebcf085..7ac4ab7 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -76,30 +76,27 @@
typedef struct DIR DIR;
-DIR* opendir(const char*);
-DIR* fdopendir(int);
-struct dirent* readdir(DIR*);
-struct dirent64* readdir64(DIR*) __INTRODUCED_IN(21);
-int readdir_r(DIR*, struct dirent*, struct dirent**);
-int readdir64_r(DIR*, struct dirent64*, struct dirent64**) __INTRODUCED_IN(21);
-int closedir(DIR*);
-void rewinddir(DIR*);
-void seekdir(DIR*, long) __INTRODUCED_IN(23);
-long telldir(DIR*) __INTRODUCED_IN(23);
-int dirfd(DIR*);
-int alphasort(const struct dirent**, const struct dirent**);
-int alphasort64(const struct dirent64**, const struct dirent64**) __INTRODUCED_IN(21);
-int scandir64(const char*, struct dirent64***, int (*)(const struct dirent64*),
- int (*)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(21);
-int scandir(const char*, struct dirent***, int (*)(const struct dirent*), int (*)(const struct dirent**, const struct dirent**));
+DIR* opendir(const char* __path);
+DIR* fdopendir(int __dir_fd);
+struct dirent* readdir(DIR* __dir);
+struct dirent64* readdir64(DIR* __dir) __INTRODUCED_IN(21);
+int readdir_r(DIR* __dir, struct dirent* __entry, struct dirent** __buffer);
+int readdir64_r(DIR* __dir, struct dirent64* __entry, struct dirent64** __buffer) __INTRODUCED_IN(21);
+int closedir(DIR* __dir);
+void rewinddir(DIR* __dir);
+void seekdir(DIR* __dir, long __location) __INTRODUCED_IN(23);
+long telldir(DIR* __dir) __INTRODUCED_IN(23);
+int dirfd(DIR* __dir);
+int alphasort(const struct dirent** __lhs, const struct dirent** __rhs);
+int alphasort64(const struct dirent64** __lhs, const struct dirent64** __rhs) __INTRODUCED_IN(21);
+int scandir64(const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(21);
+int scandir(const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**));
#if defined(__USE_GNU)
-int scandirat64(int, const char*, struct dirent64***, int (*)(const struct dirent64*),
- int (*)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(24);
-int scandirat(int, const char*, struct dirent***, int (*)(const struct dirent*),
- int (*)(const struct dirent**, const struct dirent**)) __INTRODUCED_IN(24);
+int scandirat64(int __dir_fd, const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(24);
+int scandirat(int __dir_fd, const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**)) __INTRODUCED_IN(24);
#endif
__END_DECLS
-#endif /* _DIRENT_H_ */
+#endif
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index 018482d..68d8bc9 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -34,11 +34,6 @@
__BEGIN_DECLS
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
typedef struct {
/* Pathname of shared object that contains address. */
const char* dli_fname;
@@ -50,12 +45,12 @@
void* dli_saddr;
} Dl_info;
-void* dlopen(const char* filename, int flag);
-int dlclose(void* _Nonnull handle);
+void* dlopen(const char* __filename, int __flag);
+int dlclose(void* __handle);
char* dlerror(void);
-void* dlsym(void* handle, const char* _Nonnull symbol);
-void* dlvsym(void* handle, const char* _Nonnull symbol, const char* _Nonnull version) __INTRODUCED_IN(24);
-int dladdr(const void* addr, Dl_info* _Nonnull info);
+void* dlsym(void* __handle, const char* __symbol);
+void* dlvsym(void* __handle, const char* __symbol, const char* __version) __INTRODUCED_IN(24);
+int dladdr(const void* __addr, Dl_info* __info);
#define RTLD_LOCAL 0
#define RTLD_LAZY 0x00001
@@ -80,10 +75,6 @@
#define RTLD_NEXT __BIONIC_CAST(reinterpret_cast, void*, 0xfffffffe)
#endif
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
__END_DECLS
-#endif /* __DLFCN_H */
+#endif
diff --git a/libc/include/err.h b/libc/include/err.h
index ca62c9e..a64d01d 100644
--- a/libc/include/err.h
+++ b/libc/include/err.h
@@ -35,23 +35,20 @@
#ifndef _ERR_H_
#define _ERR_H_
+#include <stdarg.h>
#include <sys/cdefs.h>
#include <sys/types.h>
__BEGIN_DECLS
-/* printf's format string isn't nullable; the err family's one is,
- * so we can't use __errlike here. */
-#define __errlike(x, y) __attribute__((__format__(printf, x, y)))
-
-__noreturn void err(int, const char *, ...) __errlike(2, 3);
-__noreturn void verr(int, const char *, __va_list) __errlike(2, 0);
-__noreturn void errx(int, const char *, ...) __errlike(2, 3);
-__noreturn void verrx(int, const char *, __va_list) __errlike(2, 0);
-void warn(const char *, ...) __errlike(1, 2);
-void vwarn(const char *, __va_list) __errlike(1, 0);
-void warnx(const char *, ...) __errlike(1, 2);
-void vwarnx(const char *, __va_list) __errlike(1, 0);
+__noreturn void err(int __status, const char* __fmt, ...) __printflike(2, 3);
+__noreturn void verr(int __status, const char* __fmt, va_list __args) __printflike(2, 0);
+__noreturn void errx(int __status, const char* __fmt, ...) __printflike(2, 3);
+__noreturn void verrx(int __status, const char* __fmt, va_list __args) __printflike(2, 0);
+void warn(const char* __fmt, ...) __printflike(1, 2);
+void vwarn(const char* __fmt, va_list __args) __printflike(1, 0);
+void warnx(const char* __fmt, ...) __printflike(1, 2);
+void vwarnx(const char* __fmt, va_list __args) __printflike(1, 0);
__END_DECLS
diff --git a/libc/include/error.h b/libc/include/error.h
index 05ce35d..d612994 100644
--- a/libc/include/error.h
+++ b/libc/include/error.h
@@ -33,12 +33,12 @@
__BEGIN_DECLS
-extern void (* _Nullable error_print_progname)(void) __INTRODUCED_IN(23);
+extern void (*error_print_progname)(void) __INTRODUCED_IN(23);
extern unsigned int error_message_count __INTRODUCED_IN(23);
extern int error_one_per_line __INTRODUCED_IN(23);
-void error(int, int, const char* _Nonnull, ...) __printflike(3, 4) __INTRODUCED_IN(23);
-void error_at_line(int, int, const char* _Nullable, unsigned int, const char* _Nonnull, ...)
+void error(int __status, int __errno, const char* __fmt, ...) __printflike(3, 4) __INTRODUCED_IN(23);
+void error_at_line(int __status, int __errno, const char* __filename, unsigned int __line_number, const char* __fmt, ...)
__printflike(5, 6) __INTRODUCED_IN(23);
__END_DECLS
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index c98022c..4852f5f 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -69,150 +69,32 @@
#define SYNC_FILE_RANGE_WAIT_AFTER 4
#endif
-int creat(const char*, mode_t);
-int creat64(const char*, mode_t) __INTRODUCED_IN(21);
-int openat(int, const char*, int, ...) __overloadable
- __RENAME_CLANG(openat);
-int openat64(int, const char*, int, ...) __INTRODUCED_IN(21);
-int open(const char*, int, ...) __overloadable __RENAME_CLANG(open);
-int open64(const char*, int, ...) __INTRODUCED_IN(21);
-ssize_t splice(int, off64_t*, int, off64_t*, size_t, unsigned int) __INTRODUCED_IN(21);
-ssize_t tee(int, int, size_t, unsigned int) __INTRODUCED_IN(21);
-ssize_t vmsplice(int, const struct iovec*, size_t, unsigned int) __INTRODUCED_IN(21);
+int creat(const char* __path, mode_t __mode);
+int creat64(const char* __path, mode_t __mode) __INTRODUCED_IN(21);
+int openat(int __dir_fd, const char* __path, int __flags, ...) __overloadable __RENAME_CLANG(openat);
+int openat64(int __dir_fd, const char* __path, int __flags, ...) __INTRODUCED_IN(21);
+int open(const char* __path, int __flags, ...) __overloadable __RENAME_CLANG(open);
+int open64(const char* __path, int __flags, ...) __INTRODUCED_IN(21);
+ssize_t splice(int __in_fd, off64_t* __in_offset, int __out_fd, off64_t* __out_offset, size_t __length, unsigned int __flags) __INTRODUCED_IN(21);
+ssize_t tee(int __in_fd, int __out_fd, size_t __length, unsigned int __flags) __INTRODUCED_IN(21);
+ssize_t vmsplice(int __fd, const struct iovec* __iov, size_t __count, unsigned int __flags) __INTRODUCED_IN(21);
-#if defined(__USE_FILE_OFFSET64)
-int fallocate(int, int, off_t, off_t) __RENAME(fallocate64) __INTRODUCED_IN(21);
-int posix_fadvise(int, off_t, off_t, int) __RENAME(posix_fadvise64) __INTRODUCED_IN(21);
-int posix_fallocate(int, off_t, off_t) __RENAME(posix_fallocate64) __INTRODUCED_IN(21);
-#else
-int fallocate(int, int, off_t, off_t) __INTRODUCED_IN(21);
-int posix_fadvise(int, off_t, off_t, int) __INTRODUCED_IN(21);
-int posix_fallocate(int, off_t, off_t) __INTRODUCED_IN(21);
-#endif
-int fallocate64(int, int, off64_t, off64_t) __INTRODUCED_IN(21);
-int posix_fadvise64(int, off64_t, off64_t, int) __INTRODUCED_IN(21);
-int posix_fallocate64(int, off64_t, off64_t) __INTRODUCED_IN(21);
+int fallocate(int __fd, int __mode, off_t __offset, off_t __length) __RENAME_IF_FILE_OFFSET64(fallocate64) __INTRODUCED_IN(21);
+int fallocate64(int __fd, int __mode, off64_t __offset, off64_t __length) __INTRODUCED_IN(21);
+int posix_fadvise(int __fd, off_t __offset, off_t __length, int __advice) __RENAME_IF_FILE_OFFSET64(posix_fadvise64) __INTRODUCED_IN(21);
+int posix_fadvise64(int __fd, off64_t __offset, off64_t __length, int __advice) __INTRODUCED_IN(21);
+int posix_fallocate(int __fd, off_t __offset, off_t __length) __RENAME_IF_FILE_OFFSET64(posix_fallocate64) __INTRODUCED_IN(21);
+int posix_fallocate64(int __fd, off64_t __offset, off64_t __length) __INTRODUCED_IN(21);
#if defined(__USE_GNU)
-ssize_t readahead(int, off64_t, size_t) __INTRODUCED_IN(16);
-int sync_file_range(int, off64_t, off64_t, unsigned int) __INTRODUCED_IN(26);
+ssize_t readahead(int __fd, off64_t __offset, size_t __length) __INTRODUCED_IN(16);
+int sync_file_range(int __fd, off64_t __offset, off64_t __length, unsigned int __flags) __INTRODUCED_IN(26);
#endif
-int __open_2(const char*, int) __INTRODUCED_IN(17);
-int __openat_2(int, const char*, int) __INTRODUCED_IN(17);
-/*
- * These are the easiest way to call the real open even in clang FORTIFY.
- */
-int __open_real(const char*, int, ...) __RENAME(open);
-int __openat_real(int, const char*, int, ...) __RENAME(openat);
-
-
-#if defined(__BIONIC_FORTIFY)
-#define __open_too_many_args_error "too many arguments"
-#define __open_too_few_args_error "called with O_CREAT, but missing mode"
-#if defined(__clang__)
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
- __errorattr(__open_too_many_args_error);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int open(const char* pathname, int flags) __overloadable
- __enable_if(flags & O_CREAT, __open_too_few_args_error)
- __errorattr(__open_too_few_args_error);
-
-/*
- * pass_object_size serves two purposes here, neither of which involve __bos: it
- * disqualifies this function from having its address taken (so &open works),
- * and it makes overload resolution prefer open(const char *, int) over
- * open(const char *, int, ...).
- */
-__BIONIC_FORTIFY_INLINE
-int open(const char* const __pass_object_size pathname,
- int flags) __overloadable {
- return __open_2(pathname, flags);
-}
-
-__BIONIC_FORTIFY_INLINE
-int open(const char* const __pass_object_size pathname, int flags, mode_t modes)
- __overloadable {
- return __open_real(pathname, flags, modes);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int openat(int dirfd, const char* pathname, int flags) __overloadable
- __enable_if(flags & O_CREAT, __open_too_few_args_error)
- __errorattr(__open_too_few_args_error);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int openat(int dirfd, const char* pathname, int flags, mode_t modes, ...)
- __overloadable
- __errorattr(__open_too_many_args_error);
-
-__BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* const __pass_object_size pathname,
- int flags) __overloadable {
- return __openat_2(dirfd, pathname, flags);
-}
-
-__BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* const __pass_object_size pathname, int flags,
- mode_t modes) __overloadable {
- return __openat_real(dirfd, pathname, flags, modes);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#else /* defined(__clang__) */
-__errordecl(__creat_missing_mode, __open_too_few_args_error);
-__errordecl(__creat_too_many_args, __open_too_many_args_error);
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-int open(const char* pathname, int flags, ...) {
- if (__builtin_constant_p(flags)) {
- if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
- __creat_missing_mode(); /* Compile time error. */
- }
- }
-
- if (__builtin_va_arg_pack_len() > 1) {
- __creat_too_many_args(); /* Compile time error. */
- }
-
- if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
- return __open_2(pathname, flags);
- }
-
- return __open_real(pathname, flags, __builtin_va_arg_pack());
-}
-
-__BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* pathname, int flags, ...) {
- if (__builtin_constant_p(flags)) {
- if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
- __creat_missing_mode(); /* Compile time error. */
- }
- }
-
- if (__builtin_va_arg_pack_len() > 1) {
- __creat_too_many_args(); /* Compile time error. */
- }
-
- if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
- return __openat_2(dirfd, pathname, flags);
- }
-
- return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#endif /* defined(__clang__) */
-
-#undef __open_too_many_args_error
-#undef __open_too_few_args_error
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/fcntl.h>
+#endif
__END_DECLS
-#endif /* _FCNTL_H */
+#endif
diff --git a/libc/include/fenv.h b/libc/include/fenv.h
index a4c37e6..ae35ae3 100644
--- a/libc/include/fenv.h
+++ b/libc/include/fenv.h
@@ -37,25 +37,25 @@
// fenv was always available on x86.
#if __ANDROID_API__ >= __ANDROID_API_L__ || defined(__i386__)
-int feclearexcept(int) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
-int fegetexceptflag(fexcept_t*, int) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21)
+int feclearexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
+int fegetexceptflag(fexcept_t* __flag_ptr, int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21)
__INTRODUCED_IN_X86(9);
-int feraiseexcept(int) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
-int fesetexceptflag(const fexcept_t*, int) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21)
+int feraiseexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
+int fesetexceptflag(const fexcept_t* __flag_ptr, int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21)
__INTRODUCED_IN_X86(9);
-int fetestexcept(int) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
+int fetestexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
int fegetround(void) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
-int fesetround(int) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
+int fesetround(int __rounding_mode) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
-int fegetenv(fenv_t*) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
-int feholdexcept(fenv_t*) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
-int fesetenv(const fenv_t*) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
-int feupdateenv(const fenv_t*) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21)
+int fegetenv(fenv_t* __env) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
+int feholdexcept(fenv_t* __env) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
+int fesetenv(const fenv_t* __env) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
+int feupdateenv(const fenv_t* __env) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21)
__INTRODUCED_IN_X86(9);
-int feenableexcept(int) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
-int fedisableexcept(int) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
+int feenableexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
+int fedisableexcept(int __exceptions) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
int fegetexcept(void) __INTRODUCED_IN_ARM(21) __INTRODUCED_IN_MIPS(21) __INTRODUCED_IN_X86(9);
#else
/* Defined as inlines for pre-21 ARM and MIPS. */
diff --git a/libc/include/fnmatch.h b/libc/include/fnmatch.h
index 1a5348b..3fcc665 100644
--- a/libc/include/fnmatch.h
+++ b/libc/include/fnmatch.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _FNMATCH_H
#define _FNMATCH_H
@@ -44,8 +45,8 @@
#define FNM_IGNORECASE FNM_CASEFOLD
#define FNM_FILE_NAME FNM_PATHNAME
-int fnmatch(const char* pattern, const char* string, int flags);
+int fnmatch(const char* __pattern, const char* __string, int __flags);
__END_DECLS
-#endif /* _FNMATCH_H */
+#endif
diff --git a/libc/include/fts.h b/libc/include/fts.h
index b46c19c..8658fab 100644
--- a/libc/include/fts.h
+++ b/libc/include/fts.h
@@ -115,12 +115,18 @@
} FTSENT;
__BEGIN_DECLS
-FTSENT *fts_children(FTS *, int);
-int fts_close(FTS *);
-FTS *fts_open(char * const *, int,
- int (*)(const FTSENT **, const FTSENT **));
-FTSENT *fts_read(FTS *);
-int fts_set(FTS *, FTSENT *, int);
+
+/*
+ * Strictly these functions were available before Lollipop/21, but there was an accidental ABI
+ * breakage in 21 that means you can't write code that runs on current devices and pre-21 devices,
+ * so we break the tie in favor of current and future devices.
+ */
+FTSENT* fts_children(FTS* __fts, int __options) __INTRODUCED_IN(21);
+int fts_close(FTS* __fts) __INTRODUCED_IN(21);
+FTS* fts_open(char* const* __path, int __options, int (*__comparator)(const FTSENT** __lhs, const FTSENT** __rhs)) __INTRODUCED_IN(21);
+FTSENT* fts_read(FTS* __fts) __INTRODUCED_IN(21);
+int fts_set(FTS* __fts, FTSENT* __entry, int __options) __INTRODUCED_IN(21);
+
__END_DECLS
#endif /* !_FTS_H_ */
diff --git a/libc/include/ftw.h b/libc/include/ftw.h
index cb8ae7d..300f624 100644
--- a/libc/include/ftw.h
+++ b/libc/include/ftw.h
@@ -55,12 +55,12 @@
};
__BEGIN_DECLS
-int ftw(const char*, int (*)(const char*, const struct stat*, int), int) __INTRODUCED_IN(17);
-int nftw(const char*, int (*)(const char*, const struct stat*, int, struct FTW*), int, int)
+int ftw(const char* __dir_path, int (*__callback)(const char*, const struct stat*, int), int __max_fd_count) __INTRODUCED_IN(17);
+int nftw(const char* __dir_path, int (*__callback)(const char*, const struct stat*, int, struct FTW*), int __max_fd_count, int __flags)
__INTRODUCED_IN(17);
-int ftw64(const char*, int (*)(const char*, const struct stat64*, int), int) __INTRODUCED_IN(21);
-int nftw64(const char*, int (*)(const char*, const struct stat64*, int, struct FTW*), int, int)
+int ftw64(const char* __dir_path, int (*__callback)(const char*, const struct stat64*, int), int __max_fd_count) __INTRODUCED_IN(21);
+int nftw64(const char* __dir_path, int (*__callback)(const char*, const struct stat64*, int, struct FTW*), int __max_fd_count, int __flags)
__INTRODUCED_IN(21);
__END_DECLS
-#endif /* !_FTW_H */
+#endif
diff --git a/libc/include/getopt.h b/libc/include/getopt.h
index 46d2eb7..c5a6106 100644
--- a/libc/include/getopt.h
+++ b/libc/include/getopt.h
@@ -59,10 +59,8 @@
};
__BEGIN_DECLS
-int getopt_long(int, char * const *, const char *,
- const struct option *, int *);
-int getopt_long_only(int, char * const *, const char *,
- const struct option *, int *);
+int getopt_long(int __argc, char* const* __argv, const char* __options, const struct option* __long_options, int* __long_index);
+int getopt_long_only(int __argc, char* const* __argv, const char* __options, const struct option* __long_options, int* __long_index);
#ifndef _OPTRESET_DECLARED
#define _OPTRESET_DECLARED
@@ -70,4 +68,4 @@
#endif
__END_DECLS
-#endif /* !_GETOPT_H_ */
+#endif
diff --git a/libc/include/grp.h b/libc/include/grp.h
index b727562..9d67adf 100644
--- a/libc/include/grp.h
+++ b/libc/include/grp.h
@@ -47,19 +47,19 @@
__BEGIN_DECLS
-struct group* getgrgid(gid_t);
-struct group* getgrnam(const char*);
+struct group* getgrgid(gid_t __gid);
+struct group* getgrnam(const char* __name);
/* Note: Android has thousands and thousands of ids to iterate through. */
struct group* getgrent(void) __INTRODUCED_IN(26);
void setgrent(void) __INTRODUCED_IN(26);
void endgrent(void) __INTRODUCED_IN(26);
-int getgrgid_r(gid_t, struct group*, char*, size_t, struct group**) __INTRODUCED_IN(24);
-int getgrnam_r(const char*, struct group*, char*, size_t, struct group**) __INTRODUCED_IN(24);
-int getgrouplist (const char*, gid_t, gid_t*, int*);
-int initgroups (const char*, gid_t);
+int getgrgid_r(gid_t __gid, struct group* __group, char* __buf, size_t __n, struct group** __result) __INTRODUCED_IN(24);
+int getgrnam_r(const char* __name, struct group* __group, char* __buf, size_t __n, struct group** __result) __INTRODUCED_IN(24);
+int getgrouplist(const char* __user, gid_t __group, gid_t* __groups, int* __group_count);
+int initgroups(const char* __user, gid_t __group);
__END_DECLS
-#endif /* !_GRP_H_ */
+#endif
diff --git a/libc/bionic/__strcpy_chk.cpp b/libc/include/iconv.h
similarity index 71%
rename from libc/bionic/__strcpy_chk.cpp
rename to libc/include/iconv.h
index 116fff4..4b05bae 100644
--- a/libc/bionic/__strcpy_chk.cpp
+++ b/libc/include/iconv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,16 +26,21 @@
* SUCH DAMAGE.
*/
-#undef _FORTIFY_SOURCE
+#ifndef _ICONV_H_
+#define _ICONV_H_
-#include <string.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
-#include "private/bionic_fortify.h"
+__BEGIN_DECLS
-// Runtime implementation of __builtin____strcpy_chk (used directly by compiler, not in headers).
-extern "C" char* __strcpy_chk(char* dst, const char* src, size_t dst_len) {
- // TODO: optimize so we don't scan src twice.
- size_t src_len = strlen(src) + 1;
- __check_buffer_access("strcpy", "write into", src_len, dst_len);
- return strcpy(dst, src);
-}
+struct __iconv_t;
+typedef struct __iconv_t* iconv_t;
+
+iconv_t iconv_open(const char* __src_encoding, const char* __dst_encoding) __INTRODUCED_IN_FUTURE;
+size_t iconv(iconv_t __converter, char** __src_buf, size_t* __src_bytes_left, char** __dst_buf, size_t* __dst_bytes_left) __INTRODUCED_IN_FUTURE;
+int iconv_close(iconv_t __converter) __INTRODUCED_IN_FUTURE;
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/ifaddrs.h b/libc/include/ifaddrs.h
index 083b27a..0e2b0ea 100644
--- a/libc/include/ifaddrs.h
+++ b/libc/include/ifaddrs.h
@@ -51,8 +51,8 @@
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
-void freeifaddrs(struct ifaddrs*) __INTRODUCED_IN(24);
-int getifaddrs(struct ifaddrs**) __INTRODUCED_IN(24);
+void freeifaddrs(struct ifaddrs* __ptr) __INTRODUCED_IN(24);
+int getifaddrs(struct ifaddrs** __list_ptr) __INTRODUCED_IN(24);
__END_DECLS
diff --git a/libc/include/inttypes.h b/libc/include/inttypes.h
index f74afa3..7a409d8 100644
--- a/libc/include/inttypes.h
+++ b/libc/include/inttypes.h
@@ -255,12 +255,12 @@
} imaxdiv_t;
__BEGIN_DECLS
-intmax_t imaxabs(intmax_t) __attribute_const__ __INTRODUCED_IN(19);
-imaxdiv_t imaxdiv(intmax_t, intmax_t) __attribute_const__ __INTRODUCED_IN(19);
-intmax_t strtoimax(const char *, char **, int);
-uintmax_t strtoumax(const char *, char **, int);
-intmax_t wcstoimax(const wchar_t* __restrict, wchar_t** __restrict, int) __INTRODUCED_IN(21);
-uintmax_t wcstoumax(const wchar_t* __restrict, wchar_t** __restrict, int) __INTRODUCED_IN(21);
+intmax_t imaxabs(intmax_t __i) __attribute_const__ __INTRODUCED_IN(19);
+imaxdiv_t imaxdiv(intmax_t __numerator, intmax_t __denominator) __attribute_const__ __INTRODUCED_IN(19);
+intmax_t strtoimax(const char* __s, char** __end_ptr, int __base);
+uintmax_t strtoumax(const char* __s, char** __end_ptr, int __base);
+intmax_t wcstoimax(const wchar_t* __s, wchar_t** __end_ptr, int __base) __INTRODUCED_IN(21);
+uintmax_t wcstoumax(const wchar_t* __s, wchar_t** __end_ptr, int __base) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* _INTTYPES_H_ */
+#endif
diff --git a/libc/include/langinfo.h b/libc/include/langinfo.h
index c330117..d9d8c15 100644
--- a/libc/include/langinfo.h
+++ b/libc/include/langinfo.h
@@ -92,8 +92,8 @@
#define NOEXPR 54
#define CRNCYSTR 55
-char* nl_langinfo(nl_item) __INTRODUCED_IN(26);
-char* nl_langinfo_l(nl_item, locale_t) __INTRODUCED_IN(26);
+char* nl_langinfo(nl_item __item) __INTRODUCED_IN(26);
+char* nl_langinfo_l(nl_item __item, locale_t __l) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/libc/include/libgen.h b/libc/include/libgen.h
index f864ee1..5fa9089 100644
--- a/libc/include/libgen.h
+++ b/libc/include/libgen.h
@@ -32,7 +32,6 @@
#include <sys/cdefs.h>
#include <sys/types.h>
-
__BEGIN_DECLS
/*
@@ -42,19 +41,19 @@
* Note that this has the wrong argument cv-qualifiers, but doesn't modify its
* input and uses thread-local storage for the result if necessary.
*/
-char* __posix_basename(const char*) __RENAME(basename);
+char* __posix_basename(const char* __path) __RENAME(basename);
#define basename __posix_basename
/* This has the wrong argument cv-qualifiers, but doesn't modify its input and uses thread-local storage for the result if necessary. */
-char* dirname(const char*);
+char* dirname(const char* __path);
#if !defined(__LP64__)
/* These non-standard functions are not needed on Android; basename and dirname use thread-local storage. */
-int dirname_r(const char*, char*, size_t);
-int basename_r(const char*, char*, size_t);
+int dirname_r(const char* __path, char* __buf, size_t __n);
+int basename_r(const char* __path, char* __buf, size_t __n);
#endif
__END_DECLS
-#endif /* _LIBGEN_H */
+#endif
diff --git a/libc/include/limits.h b/libc/include/limits.h
index 157f7a6..51f4fad 100644
--- a/libc/include/limits.h
+++ b/libc/include/limits.h
@@ -137,6 +137,8 @@
#include <bits/posix_limits.h>
#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
+#define LOGIN_NAME_MAX 256
+#define TTY_NAME_MAX 32
#define _POSIX_VERSION 200809L
#define _POSIX2_VERSION _POSIX_VERSION
diff --git a/libc/include/link.h b/libc/include/link.h
index dd3b99f..072f093 100644
--- a/libc/include/link.h
+++ b/libc/include/link.h
@@ -50,9 +50,9 @@
};
#if defined(__arm__)
-int dl_iterate_phdr(int (*)(struct dl_phdr_info*, size_t, void*), void*) __INTRODUCED_IN(21);
+int dl_iterate_phdr(int (*__callback)(struct dl_phdr_info*, size_t, void*), void* __data) __INTRODUCED_IN(21);
#else
-int dl_iterate_phdr(int (*)(struct dl_phdr_info*, size_t, void*), void*);
+int dl_iterate_phdr(int (*__callback)(struct dl_phdr_info*, size_t, void*), void* __data);
#endif
#ifdef __arm__
@@ -84,4 +84,4 @@
__END_DECLS
-#endif /* _LINK_H_ */
+#endif
diff --git a/libc/include/locale.h b/libc/include/locale.h
index c1b6299..4290992 100644
--- a/libc/include/locale.h
+++ b/libc/include/locale.h
@@ -98,14 +98,14 @@
struct lconv* localeconv(void) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;
-locale_t duplocale(locale_t) __INTRODUCED_IN(21);
-void freelocale(locale_t) __INTRODUCED_IN(21);
-locale_t newlocale(int, const char*, locale_t) __INTRODUCED_IN(21);
-char* setlocale(int, const char*);
-locale_t uselocale(locale_t) __INTRODUCED_IN(21);
+locale_t duplocale(locale_t __l) __INTRODUCED_IN(21);
+void freelocale(locale_t __l) __INTRODUCED_IN(21);
+locale_t newlocale(int __category_mask, const char* __locale_name, locale_t __base) __INTRODUCED_IN(21);
+char* setlocale(int __category, const char* __locale_name);
+locale_t uselocale(locale_t __l) __INTRODUCED_IN(21);
#define LC_GLOBAL_LOCALE __BIONIC_CAST(reinterpret_cast, locale_t, -1L)
__END_DECLS
-#endif /* _LOCALE_H_ */
+#endif
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index db5da04..80b08f6 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -30,13 +30,13 @@
#define __BIONIC_ALLOC_SIZE(...) __attribute__((__alloc_size__(__VA_ARGS__)))
#endif
-void* malloc(size_t byte_count) __mallocfunc __BIONIC_ALLOC_SIZE(1) __wur;
-void* calloc(size_t item_count, size_t item_size) __mallocfunc __BIONIC_ALLOC_SIZE(1,2) __wur;
-void* realloc(void* p, size_t byte_count) __BIONIC_ALLOC_SIZE(2) __wur;
-void free(void* p);
+void* malloc(size_t __byte_count) __mallocfunc __BIONIC_ALLOC_SIZE(1) __wur;
+void* calloc(size_t __item_count, size_t __item_size) __mallocfunc __BIONIC_ALLOC_SIZE(1,2) __wur;
+void* realloc(void* __ptr, size_t __byte_count) __BIONIC_ALLOC_SIZE(2) __wur;
+void free(void* __ptr);
-void* memalign(size_t alignment, size_t byte_count) __mallocfunc __BIONIC_ALLOC_SIZE(2) __wur;
-size_t malloc_usable_size(const void* p) __INTRODUCED_IN(17);
+void* memalign(size_t __alignment, size_t __byte_count) __mallocfunc __BIONIC_ALLOC_SIZE(2) __wur;
+size_t malloc_usable_size(const void* __ptr) __INTRODUCED_IN(17);
#ifndef STRUCT_MALLINFO_DECLARED
#define STRUCT_MALLINFO_DECLARED 1
@@ -75,12 +75,11 @@
* <!-- more heaps -->
* </malloc>
*/
-int malloc_info(int, FILE*) __INTRODUCED_IN(23);
+int malloc_info(int __must_be_zero, FILE* __fp) __INTRODUCED_IN(23);
/* mallopt options */
#define M_DECAY_TIME -100
-
-int mallopt(int, int) __INTRODUCED_IN(26);
+int mallopt(int __option, int __value) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/libc/include/math.h b/libc/include/math.h
index 7dd1539..248ed3c 100644
--- a/libc/include/math.h
+++ b/libc/include/math.h
@@ -89,69 +89,69 @@
* as __attribute_const__. In C99, FENV_ACCESS affects the purity of these functions.
*/
-int __fpclassifyd(double) __attribute_const__;
-int __fpclassifyf(float) __attribute_const__;
-int __fpclassifyl(long double) __attribute_const__;
-int __isfinitef(float) __attribute_const__;
-int __isfinite(double) __attribute_const__;
-int __isfinitel(long double) __attribute_const__;
-int __isinff(float) __attribute_const__;
-int __isinfl(long double) __attribute_const__;
-int __isnanf(float) __attribute_const__ __INTRODUCED_IN(21);
-int __isnanl(long double) __attribute_const__;
-int __isnormalf(float) __attribute_const__;
-int __isnormal(double) __attribute_const__;
-int __isnormall(long double) __attribute_const__;
-int __signbit(double) __attribute_const__;
-int __signbitf(float) __attribute_const__;
-int __signbitl(long double) __attribute_const__;
+int __fpclassifyd(double __x) __attribute_const__;
+int __fpclassifyf(float __x) __attribute_const__;
+int __fpclassifyl(long double __x) __attribute_const__;
+int __isfinitef(float __x) __attribute_const__;
+int __isfinite(double __x) __attribute_const__;
+int __isfinitel(long double __x) __attribute_const__;
+int __isinff(float __x) __attribute_const__;
+int __isinfl(long double __x) __attribute_const__;
+int __isnanf(float __x) __attribute_const__ __INTRODUCED_IN(21);
+int __isnanl(long double __x) __attribute_const__;
+int __isnormalf(float __x) __attribute_const__;
+int __isnormal(double __x) __attribute_const__;
+int __isnormall(long double __x) __attribute_const__;
+int __signbit(double __x) __attribute_const__;
+int __signbitf(float __x) __attribute_const__;
+int __signbitl(long double __x) __attribute_const__;
-double acos(double);
-double asin(double);
-double atan(double);
-double atan2(double, double);
-double cos(double);
-double sin(double);
-double tan(double);
+double acos(double __x);
+double asin(double __x);
+double atan(double __x);
+double atan2(double __y, double __x);
+double cos(double __x);
+double sin(double __x);
+double tan(double __x);
-double cosh(double);
-double sinh(double);
-double tanh(double);
+double cosh(double __x);
+double sinh(double __x);
+double tanh(double __x);
-double exp(double);
-double frexp(double, int *); /* fundamentally !__attribute_const__ */
-double ldexp(double, int);
-double log(double);
-double log10(double);
-double modf(double, double *); /* fundamentally !__attribute_const__ */
+double exp(double __x);
+double frexp(double __x, int* __exponent); /* fundamentally !__attribute_const__ */
+double ldexp(double __x, int __exponent);
+double log(double __x);
+double log10(double __x);
+double modf(double __x, double* __integral_part); /* fundamentally !__attribute_const__ */
-double pow(double, double);
-double sqrt(double);
+double pow(double __x, double __y);
+double sqrt(double __x);
-double ceil(double);
-double fabs(double) __attribute_const__;
-double floor(double);
-double fmod(double, double);
+double ceil(double __x);
+double fabs(double __x) __attribute_const__;
+double floor(double __x);
+double fmod(double __x, double __y);
-double acosh(double);
-double asinh(double);
-double atanh(double);
-double cbrt(double);
-double erf(double);
-double erfc(double);
-double exp2(double);
-double expm1(double);
-double fma(double, double, double);
-double hypot(double, double);
-int ilogb(double) __attribute_const__;
-double lgamma(double);
-long long llrint(double);
-long long llround(double);
-double log1p(double);
-double log2(double) __INTRODUCED_IN(18);
-double logb(double);
-long lrint(double);
-long lround(double);
+double acosh(double __x);
+double asinh(double __x);
+double atanh(double __x);
+double cbrt(double __x);
+double erf(double __x);
+double erfc(double __x);
+double exp2(double __x);
+double expm1(double __x);
+double fma(double __x, double __y, double __z);
+double hypot(double __x, double __y);
+int ilogb(double __x) __attribute_const__;
+double lgamma(double __x);
+long long llrint(double __x);
+long long llround(double __x);
+double log1p(double __x);
+double log2(double __x) __INTRODUCED_IN(18);
+double logb(double __x);
+long lrint(double __x);
+long lround(double __x);
/*
* https://code.google.com/p/android/issues/detail?id=271629
@@ -164,160 +164,160 @@
* to the std namespace, making it impossible to use both <cmath> (which gets
* included by a lot of other standard headers) and ::isnan.
*/
-int(isinf)(double) __attribute_const__ __INTRODUCED_IN(21);
-int (isnan)(double) __attribute_const__;
+int (isinf)(double __x) __attribute_const__ __INTRODUCED_IN(21);
+int (isnan)(double __x) __attribute_const__;
-double nan(const char*) __attribute_const__ __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(13)
+double nan(const char* __kind) __attribute_const__ __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(13)
__INTRODUCED_IN_X86(9);
-double nextafter(double, double);
-double remainder(double, double);
-double remquo(double, double, int*);
-double rint(double);
+double nextafter(double __x, double __y);
+double remainder(double __x, double __y);
+double remquo(double __x, double __y, int* __quotient_bits);
+double rint(double __x);
-double copysign(double, double) __attribute_const__;
-double fdim(double, double);
-double fmax(double, double) __attribute_const__;
-double fmin(double, double) __attribute_const__;
-double nearbyint(double);
-double round(double);
-double scalbln(double, long) __INTRODUCED_IN_X86(18) __VERSIONER_NO_GUARD;
-double scalbn(double, int);
-double tgamma(double);
-double trunc(double);
+double copysign(double __value, double __sign) __attribute_const__;
+double fdim(double __x, double __y);
+double fmax(double __x, double __y) __attribute_const__;
+double fmin(double __x, double __y) __attribute_const__;
+double nearbyint(double __x);
+double round(double __x);
+double scalbln(double __x, long __exponent) __INTRODUCED_IN_X86(18) __VERSIONER_NO_GUARD;
+double scalbn(double __x, int __exponent);
+double tgamma(double __x);
+double trunc(double __x);
-float acosf(float);
-float asinf(float);
-float atanf(float);
-float atan2f(float, float);
-float cosf(float);
-float sinf(float);
-float tanf(float);
+float acosf(float __x);
+float asinf(float __x);
+float atanf(float __x);
+float atan2f(float __y, float __x);
+float cosf(float __x);
+float sinf(float __x);
+float tanf(float __x);
-float coshf(float);
-float sinhf(float);
-float tanhf(float);
+float coshf(float __x);
+float sinhf(float __x);
+float tanhf(float __x);
-float exp2f(float);
-float expf(float);
-float expm1f(float);
-float frexpf(float, int *); /* fundamentally !__attribute_const__ */
-int ilogbf(float) __attribute_const__;
-float ldexpf(float, int);
-float log10f(float);
-float log1pf(float);
-float log2f(float) __INTRODUCED_IN(18);
-float logf(float);
-float modff(float, float *); /* fundamentally !__attribute_const__ */
+float exp2f(float __x);
+float expf(float __x);
+float expm1f(float __x);
+float frexpf(float __x, int* __exponent); /* fundamentally !__attribute_const__ */
+int ilogbf(float __x) __attribute_const__;
+float ldexpf(float __x, int __exponent);
+float log10f(float __x);
+float log1pf(float __x);
+float log2f(float __x) __INTRODUCED_IN(18);
+float logf(float __x);
+float modff(float __x, float* __integral_part); /* fundamentally !__attribute_const__ */
-float powf(float, float);
-float sqrtf(float);
+float powf(float __x, float __y);
+float sqrtf(float __x);
-float ceilf(float);
-float fabsf(float) __attribute_const__;
-float floorf(float);
-float fmodf(float, float);
-float roundf(float);
+float ceilf(float __x);
+float fabsf(float __x) __attribute_const__;
+float floorf(float __x);
+float fmodf(float __x, float __y);
+float roundf(float __x);
-float erff(float);
-float erfcf(float);
-float hypotf(float, float);
-float lgammaf(float);
-float tgammaf(float) __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(13) __INTRODUCED_IN_X86(9);
+float erff(float __x);
+float erfcf(float __x);
+float hypotf(float __x, float __y);
+float lgammaf(float __x);
+float tgammaf(float __x) __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(13) __INTRODUCED_IN_X86(9);
-float acoshf(float);
-float asinhf(float);
-float atanhf(float);
-float cbrtf(float);
-float logbf(float);
-float copysignf(float, float) __attribute_const__;
-long long llrintf(float);
-long long llroundf(float);
-long lrintf(float);
-long lroundf(float);
-float nanf(const char*) __attribute_const__ __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(13)
+float acoshf(float __x);
+float asinhf(float __x);
+float atanhf(float __x);
+float cbrtf(float __x);
+float logbf(float __x);
+float copysignf(float __value, float __sign) __attribute_const__;
+long long llrintf(float __x);
+long long llroundf(float __x);
+long lrintf(float __x);
+long lroundf(float __x);
+float nanf(const char* __kind) __attribute_const__ __INTRODUCED_IN_ARM(13) __INTRODUCED_IN_MIPS(13)
__INTRODUCED_IN_X86(9);
-float nearbyintf(float);
-float nextafterf(float, float);
-float remainderf(float, float);
-float remquof(float, float, int *);
-float rintf(float);
-float scalblnf(float, long) __INTRODUCED_IN_X86(18) __VERSIONER_NO_GUARD;
-float scalbnf(float, int);
-float truncf(float);
+float nearbyintf(float __x);
+float nextafterf(float __x, float __y);
+float remainderf(float __x, float __y);
+float remquof(float __x, float __y, int* __quotient_bits);
+float rintf(float __x);
+float scalblnf(float __x, long __exponent) __INTRODUCED_IN_X86(18) __VERSIONER_NO_GUARD;
+float scalbnf(float __x, int __exponent);
+float truncf(float __x);
-float fdimf(float, float);
-float fmaf(float, float, float);
-float fmaxf(float, float) __attribute_const__;
-float fminf(float, float) __attribute_const__;
+float fdimf(float __x, float __y);
+float fmaf(float __x, float __y, float __z);
+float fmaxf(float __x, float __y) __attribute_const__;
+float fminf(float __x, float __y) __attribute_const__;
-long double acoshl(long double) __INTRODUCED_IN(21);
-long double acosl(long double) __INTRODUCED_IN(21);
-long double asinhl(long double) __INTRODUCED_IN(21);
-long double asinl(long double) __INTRODUCED_IN(21);
-long double atan2l(long double, long double) __INTRODUCED_IN(21);
-long double atanhl(long double) __INTRODUCED_IN(21);
-long double atanl(long double) __INTRODUCED_IN(21);
-long double cbrtl(long double) __INTRODUCED_IN(21);
-long double ceill(long double);
-long double copysignl(long double, long double) __attribute_const__;
-long double coshl(long double) __INTRODUCED_IN(21);
-long double cosl(long double) __INTRODUCED_IN(21);
-long double erfcl(long double) __INTRODUCED_IN(21);
-long double erfl(long double) __INTRODUCED_IN(21);
-long double exp2l(long double) __INTRODUCED_IN(21);
-long double expl(long double) __INTRODUCED_IN(21);
-long double expm1l(long double) __INTRODUCED_IN(21);
-long double fabsl(long double) __attribute_const__;
-long double fdiml(long double, long double);
-long double floorl(long double);
-long double fmal(long double, long double, long double) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;
-long double fmaxl(long double, long double) __attribute_const__;
-long double fminl(long double, long double) __attribute_const__;
-long double fmodl(long double, long double) __INTRODUCED_IN(21);
-long double frexpl(long double value, int*)
+long double acoshl(long double __x) __INTRODUCED_IN(21);
+long double acosl(long double __x) __INTRODUCED_IN(21);
+long double asinhl(long double __x) __INTRODUCED_IN(21);
+long double asinl(long double __x) __INTRODUCED_IN(21);
+long double atan2l(long double __y, long double __x) __INTRODUCED_IN(21);
+long double atanhl(long double __x) __INTRODUCED_IN(21);
+long double atanl(long double __x) __INTRODUCED_IN(21);
+long double cbrtl(long double __x) __INTRODUCED_IN(21);
+long double ceill(long double __x);
+long double copysignl(long double __value, long double __sign) __attribute_const__;
+long double coshl(long double __x) __INTRODUCED_IN(21);
+long double cosl(long double __x) __INTRODUCED_IN(21);
+long double erfcl(long double __x) __INTRODUCED_IN(21);
+long double erfl(long double __x) __INTRODUCED_IN(21);
+long double exp2l(long double __x) __INTRODUCED_IN(21);
+long double expl(long double __x) __INTRODUCED_IN(21);
+long double expm1l(long double __x) __INTRODUCED_IN(21);
+long double fabsl(long double __x) __attribute_const__;
+long double fdiml(long double __x, long double __y);
+long double floorl(long double __x);
+long double fmal(long double __x, long double __y, long double __z) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;
+long double fmaxl(long double __x, long double __y) __attribute_const__;
+long double fminl(long double __x, long double __y) __attribute_const__;
+long double fmodl(long double __x, long double __y) __INTRODUCED_IN(21);
+long double frexpl(long double __x, int* __exponent)
__INTRODUCED_IN(21) __VERSIONER_NO_GUARD; /* fundamentally !__attribute_const__ */
-long double hypotl(long double, long double) __INTRODUCED_IN(21);
-int ilogbl(long double) __attribute_const__;
-long double ldexpl(long double, int);
-long double lgammal(long double) __INTRODUCED_IN(21);
-long long llrintl(long double) __INTRODUCED_IN(21);
-long long llroundl(long double);
-long double log10l(long double) __INTRODUCED_IN(21);
-long double log1pl(long double) __INTRODUCED_IN(21);
-long double log2l(long double) __INTRODUCED_IN(18);
-long double logbl(long double) __INTRODUCED_IN(18);
-long double logl(long double) __INTRODUCED_IN(21);
-long lrintl(long double) __INTRODUCED_IN(21);
-long lroundl(long double);
-long double modfl(long double, long double*) __INTRODUCED_IN(21); /* fundamentally !__attribute_const__ */
-long double nanl(const char*) __attribute_const__ __INTRODUCED_IN(13);
-long double nearbyintl(long double) __INTRODUCED_IN(21);
-long double nextafterl(long double, long double) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;
-double nexttoward(double, long double) __INTRODUCED_IN(18) __VERSIONER_NO_GUARD;
-float nexttowardf(float, long double);
-long double nexttowardl(long double, long double) __INTRODUCED_IN(18) __VERSIONER_NO_GUARD;
-long double powl(long double, long double) __INTRODUCED_IN(21);
-long double remainderl(long double, long double) __INTRODUCED_IN(21);
-long double remquol(long double, long double, int*) __INTRODUCED_IN(21);
-long double rintl(long double) __INTRODUCED_IN(21);
-long double roundl(long double);
-long double scalblnl(long double, long) __INTRODUCED_IN_X86(18) __VERSIONER_NO_GUARD;
-long double scalbnl(long double, int);
-long double sinhl(long double) __INTRODUCED_IN(21);
-long double sinl(long double) __INTRODUCED_IN(21);
-long double sqrtl(long double) __INTRODUCED_IN(21);
-long double tanhl(long double) __INTRODUCED_IN(21);
-long double tanl(long double) __INTRODUCED_IN(21);
-long double tgammal(long double) __INTRODUCED_IN(21);
-long double truncl(long double);
+long double hypotl(long double __x, long double __y) __INTRODUCED_IN(21);
+int ilogbl(long double __x) __attribute_const__;
+long double ldexpl(long double __x, int __exponent);
+long double lgammal(long double __x) __INTRODUCED_IN(21);
+long long llrintl(long double __x) __INTRODUCED_IN(21);
+long long llroundl(long double __x);
+long double log10l(long double __x) __INTRODUCED_IN(21);
+long double log1pl(long double __x) __INTRODUCED_IN(21);
+long double log2l(long double __x) __INTRODUCED_IN(18);
+long double logbl(long double __x) __INTRODUCED_IN(18);
+long double logl(long double __x) __INTRODUCED_IN(21);
+long lrintl(long double __x) __INTRODUCED_IN(21);
+long lroundl(long double __x);
+long double modfl(long double __x, long double* __integral_part) __INTRODUCED_IN(21); /* fundamentally !__attribute_const__ */
+long double nanl(const char* __kind) __attribute_const__ __INTRODUCED_IN(13);
+long double nearbyintl(long double __x) __INTRODUCED_IN(21);
+long double nextafterl(long double __x, long double __y) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;
+double nexttoward(double __x, long double __y) __INTRODUCED_IN(18) __VERSIONER_NO_GUARD;
+float nexttowardf(float __x, long double __y);
+long double nexttowardl(long double __x, long double __y) __INTRODUCED_IN(18) __VERSIONER_NO_GUARD;
+long double powl(long double __x, long double __y) __INTRODUCED_IN(21);
+long double remainderl(long double __x, long double __y) __INTRODUCED_IN(21);
+long double remquol(long double __x, long double __y, int* __quotient_bits) __INTRODUCED_IN(21);
+long double rintl(long double __x) __INTRODUCED_IN(21);
+long double roundl(long double __x);
+long double scalblnl(long double __x, long __exponent) __INTRODUCED_IN_X86(18) __VERSIONER_NO_GUARD;
+long double scalbnl(long double __x, int __exponent);
+long double sinhl(long double __x) __INTRODUCED_IN(21);
+long double sinl(long double __x) __INTRODUCED_IN(21);
+long double sqrtl(long double __x) __INTRODUCED_IN(21);
+long double tanhl(long double __x) __INTRODUCED_IN(21);
+long double tanl(long double __x) __INTRODUCED_IN(21);
+long double tgammal(long double __x) __INTRODUCED_IN(21);
+long double truncl(long double __x);
-double j0(double);
-double j1(double);
-double jn(int, double);
-double y0(double);
-double y1(double);
-double yn(int, double);
+double j0(double __x);
+double j1(double __x);
+double jn(int __n, double __x);
+double y0(double __x);
+double y1(double __x);
+double yn(int __n, double __x);
#define M_E 2.7182818284590452354 /* e */
#define M_LOG2E 1.4426950408889634074 /* log 2e */
@@ -336,29 +336,29 @@
#define MAXFLOAT ((float)3.40282346638528860e+38)
#if defined(__USE_BSD) || defined(__USE_GNU)
-double gamma(double);
-double scalb(double, double);
-double drem(double, double);
-int finite(double) __attribute_const__;
-int isnanf(float) __attribute_const__;
-double gamma_r(double, int*);
-double lgamma_r(double, int*);
-double significand(double);
-long double lgammal_r(long double, int*) __INTRODUCED_IN(23);
-long double significandl(long double) __INTRODUCED_IN(21);
-float dremf(float, float);
-int finitef(float) __attribute_const__;
-float gammaf(float);
-float j0f(float);
-float j1f(float);
-float jnf(int, float);
-float scalbf(float, float);
-float y0f(float);
-float y1f(float);
-float ynf(int, float);
-float gammaf_r(float, int *);
-float lgammaf_r(float, int *);
-float significandf(float);
+double gamma(double __x);
+double scalb(double __x, double __exponent);
+double drem(double __x, double __y);
+int finite(double __x) __attribute_const__;
+int isnanf(float __x) __attribute_const__;
+double gamma_r(double __x, int* __sign);
+double lgamma_r(double __x, int* __sign);
+double significand(double __x);
+long double lgammal_r(long double __x, int* __sign) __INTRODUCED_IN(23);
+long double significandl(long double __x) __INTRODUCED_IN(21);
+float dremf(float __x, float __y);
+int finitef(float __x) __attribute_const__;
+float gammaf(float __x);
+float j0f(float __x);
+float j1f(float __x);
+float jnf(int __n, float __x);
+float scalbf(float __x, float __exponent);
+float y0f(float __x);
+float y1f(float __x);
+float ynf(int __n, float __x);
+float gammaf_r(float __x, int* __sign);
+float lgammaf_r(float __x, int* __sign);
+float significandf(float __x);
#endif
#if defined(__USE_GNU)
@@ -375,11 +375,11 @@
#define M_2_SQRTPIl 1.128379167095512573896158903121545172L /* 2/sqrt(pi) */
#define M_SQRT2l 1.414213562373095048801688724209698079L /* sqrt(2) */
#define M_SQRT1_2l 0.707106781186547524400844362104849039L /* 1/sqrt(2) */
-void sincos(double, double*, double*);
-void sincosf(float, float*, float*);
-void sincosl(long double, long double*, long double*);
+void sincos(double __x, double* __sin, double* __cos);
+void sincosf(float __x, float* __sin, float* __cos);
+void sincosl(long double __x, long double* __sin, long double* __cos);
#endif
__END_DECLS
-#endif /* !_MATH_H_ */
+#endif
diff --git a/libc/include/mntent.h b/libc/include/mntent.h
index 551a085..d5987dc 100644
--- a/libc/include/mntent.h
+++ b/libc/include/mntent.h
@@ -57,11 +57,11 @@
__BEGIN_DECLS
-int endmntent(FILE*) __INTRODUCED_IN(21);
-struct mntent* getmntent(FILE*);
-struct mntent* getmntent_r(FILE*, struct mntent*, char*, int) __INTRODUCED_IN(21);
-FILE* setmntent(const char*, const char*) __INTRODUCED_IN(21);
-char* hasmntopt(const struct mntent*, const char*) __INTRODUCED_IN(26);
+int endmntent(FILE* __fp) __INTRODUCED_IN(21);
+struct mntent* getmntent(FILE* __fp);
+struct mntent* getmntent_r(FILE* __fp, struct mntent* __entry, char* __buf, int __size) __INTRODUCED_IN(21);
+FILE* setmntent(const char* __filename, const char* __type) __INTRODUCED_IN(21);
+char* hasmntopt(const struct mntent* __entry, const char* __option) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/libc/include/net/if.h b/libc/include/net/if.h
index eac7699..f261f71 100644
--- a/libc/include/net/if.h
+++ b/libc/include/net/if.h
@@ -44,10 +44,10 @@
char* if_name;
};
-char* if_indextoname(unsigned, char*);
-unsigned if_nametoindex(const char*);
+char* if_indextoname(unsigned __index, char* __buf);
+unsigned if_nametoindex(const char* __name);
struct if_nameindex* if_nameindex(void) __INTRODUCED_IN(24);
-void if_freenameindex(struct if_nameindex*) __INTRODUCED_IN(24);
+void if_freenameindex(struct if_nameindex* __ptr) __INTRODUCED_IN(24);
__END_DECLS
diff --git a/libc/include/netdb.h b/libc/include/netdb.h
index 816acc5..66ec8e3 100644
--- a/libc/include/netdb.h
+++ b/libc/include/netdb.h
@@ -196,37 +196,33 @@
__BEGIN_DECLS
-/* BIONIC-BEGIN */
-#define h_errno (*__get_h_errno())
-int* __get_h_errno(void);
-/* BIONIC-END */
+#define h_errno (*__get_h_errno())
+int* __get_h_errno(void);
void endservent(void);
-struct hostent* gethostbyaddr(const void*, socklen_t, int);
-int gethostbyaddr_r(const void*, socklen_t, int, struct hostent*, char*, size_t, struct hostent**,
- int*) __INTRODUCED_IN(23);
-struct hostent* gethostbyname(const char*);
-int gethostbyname_r(const char*, struct hostent*, char*, size_t, struct hostent**, int*);
-struct hostent* gethostbyname2(const char*, int);
-int gethostbyname2_r(const char*, int, struct hostent*, char*, size_t, struct hostent**, int*)
- __INTRODUCED_IN(23);
+struct hostent* gethostbyaddr(const void* __addr, socklen_t __length, int __type);
+int gethostbyaddr_r(const void* __addr, socklen_t __length, int __type, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr) __INTRODUCED_IN(23);
+struct hostent* gethostbyname(const char* __name);
+int gethostbyname_r(const char* __name, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr);
+struct hostent* gethostbyname2(const char* __name, int __af);
+int gethostbyname2_r(const char* __name, int __af, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr) __INTRODUCED_IN(23);
struct hostent* gethostent(void);
-struct netent* getnetbyaddr(uint32_t, int);
-struct netent* getnetbyname(const char*);
-struct protoent* getprotobyname(const char*);
-struct protoent* getprotobynumber(int);
-struct servent* getservbyname(const char*, const char*);
-struct servent* getservbyport(int, const char*);
+struct netent* getnetbyaddr(uint32_t __net, int __type);
+struct netent* getnetbyname(const char* __name);
+struct protoent* getprotobyname(const char* __name);
+struct protoent* getprotobynumber(int __proto);
+struct servent* getservbyname(const char* __name, const char* __proto);
+struct servent* getservbyport(int __port, const char* __proto);
struct servent* getservent(void);
-void herror(const char*);
-const char* hstrerror(int);
+void herror(const char* __s);
+const char* hstrerror(int __error);
-int getaddrinfo(const char*, const char*, const struct addrinfo*, struct addrinfo**);
+int getaddrinfo(const char* __node, const char* __service, const struct addrinfo* __hints, struct addrinfo** __result);
/* POSIX getnameinfo uses socklen_t, not size_t, but LP64 sizeof(socklen_t) != sizeof(size_t). */
-int getnameinfo(const struct sockaddr*, socklen_t, char*, size_t, char*, size_t, int);
-void freeaddrinfo(struct addrinfo*);
-const char* gai_strerror(int);
-void setservent(int);
+int getnameinfo(const struct sockaddr* __sa, socklen_t __sa_length, char* __host, size_t __host_length, char* __service, size_t __service_length, int __flags);
+void freeaddrinfo(struct addrinfo* __ptr);
+const char* gai_strerror(int __error);
+void setservent(int __stay_open);
__END_DECLS
-#endif /* !_NETDB_H_ */
+#endif
diff --git a/libc/include/netinet/ether.h b/libc/include/netinet/ether.h
index e69cdaf..3e6a4e3 100644
--- a/libc/include/netinet/ether.h
+++ b/libc/include/netinet/ether.h
@@ -34,10 +34,10 @@
__BEGIN_DECLS
-char* ether_ntoa(const struct ether_addr*) __INTRODUCED_IN(11);
-char* ether_ntoa_r(const struct ether_addr*, char*) __INTRODUCED_IN(11);
-struct ether_addr* ether_aton(const char*) __INTRODUCED_IN(11);
-struct ether_addr* ether_aton_r(const char*, struct ether_addr*) __INTRODUCED_IN(11);
+char* ether_ntoa(const struct ether_addr* __addr) __INTRODUCED_IN(11);
+char* ether_ntoa_r(const struct ether_addr* __addr, char* __buf) __INTRODUCED_IN(11);
+struct ether_addr* ether_aton(const char* __ascii) __INTRODUCED_IN(11);
+struct ether_addr* ether_aton_r(const char* __ascii, struct ether_addr* __addr) __INTRODUCED_IN(11);
__END_DECLS
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 10fbafa..0ca8c82 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -45,7 +45,7 @@
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
-int bindresvport(int, struct sockaddr_in*);
+int bindresvport(int __fd, struct sockaddr_in* __sin);
#if __ANDROID_API__ >= __ANDROID_API_N__
extern const struct in6_addr in6addr_any __INTRODUCED_IN(24);
diff --git a/libc/include/nl_types.h b/libc/include/nl_types.h
index d478353..b25b7a3 100644
--- a/libc/include/nl_types.h
+++ b/libc/include/nl_types.h
@@ -39,9 +39,9 @@
typedef void* nl_catd;
typedef int nl_item;
-nl_catd catopen(const char*, int) __INTRODUCED_IN(26);
-char* catgets(nl_catd, int, int, const char*) __INTRODUCED_IN(26);
-int catclose(nl_catd) __INTRODUCED_IN(26);
+nl_catd catopen(const char* __name, int __flag) __INTRODUCED_IN(26);
+char* catgets(nl_catd __catalog, int __set_number, int __msg_number, const char* __msg) __INTRODUCED_IN(26);
+int catclose(nl_catd __catalog) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/libc/include/paths.h b/libc/include/paths.h
index b76d045..d2c5956 100644
--- a/libc/include/paths.h
+++ b/libc/include/paths.h
@@ -34,7 +34,9 @@
#include <sys/cdefs.h>
+#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/system/bin/sh"
+#endif
#define _PATH_CONSOLE "/dev/console"
#define _PATH_DEFPATH "/sbin:/system/sbin:/system/bin:/system/xbin:/vendor/bin:/vendor/xbin"
#define _PATH_DEV "/dev/"
diff --git a/libc/include/poll.h b/libc/include/poll.h
index 3287a0c..8517dc6 100644
--- a/libc/include/poll.h
+++ b/libc/include/poll.h
@@ -38,92 +38,13 @@
typedef unsigned int nfds_t;
-int poll(struct pollfd*, nfds_t, int) __overloadable __RENAME_CLANG(poll);
-int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*)
- __overloadable __RENAME_CLANG(ppoll) __INTRODUCED_IN(21);
+int poll(struct pollfd* __fds, nfds_t __count, int __timeout_ms) __overloadable __RENAME_CLANG(poll);
+int ppoll(struct pollfd* __fds, nfds_t __count, const struct timespec* __timeout, const sigset_t* __mask) __overloadable __RENAME_CLANG(ppoll) __INTRODUCED_IN(21);
-int __poll_chk(struct pollfd*, nfds_t, int, size_t) __INTRODUCED_IN(23);
-int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t)
- __INTRODUCED_IN(23);
-
-#if defined(__BIONIC_FORTIFY)
-#if __ANDROID_API__ >= __ANDROID_API_M__
-#if defined(__clang__)
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int poll(struct pollfd* fds, nfds_t fd_count, int timeout) __overloadable
- __enable_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(fds) < sizeof(*fds) * fd_count,
- "selected when there aren't fd_count fds")
- __errorattr("too many fds specified");
-
-__BIONIC_FORTIFY_INLINE
-int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count,
- int timeout) __overloadable {
- size_t bos_fds = __bos(fds);
-
- if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(poll)(fds, fd_count, timeout);
- }
-
- return __poll_chk(fds, fd_count, timeout, bos_fds);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout,
- const sigset_t* mask) __overloadable
- __enable_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(fds) < sizeof(*fds) * fd_count,
- "selected when there aren't fd_count fds")
- __errorattr("too many fds specified");
-
-__BIONIC_FORTIFY_INLINE
-int ppoll(struct pollfd* const fds __pass_object_size, nfds_t fd_count,
- const struct timespec* timeout, const sigset_t* mask) __overloadable {
- size_t bos_fds = __bos(fds);
-
- if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(ppoll)(fds, fd_count, timeout, mask);
- }
-
- return __ppoll_chk(fds, fd_count, timeout, mask, bos_fds);
-}
-#else /* defined(__clang__) */
-int __poll_real(struct pollfd*, nfds_t, int) __RENAME(poll);
-__errordecl(__poll_too_small_error, "poll: pollfd array smaller than fd count");
-
-int __ppoll_real(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __RENAME(ppoll)
- __INTRODUCED_IN(21);
-__errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count");
-
-__BIONIC_FORTIFY_INLINE
-int poll(struct pollfd* fds, nfds_t fd_count, int timeout) {
- if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- if (!__builtin_constant_p(fd_count)) {
- return __poll_chk(fds, fd_count, timeout, __bos(fds));
- } else if (__bos(fds) / sizeof(*fds) < fd_count) {
- __poll_too_small_error();
- }
- }
- return __poll_real(fds, fd_count, timeout);
-}
-
-__BIONIC_FORTIFY_INLINE
-int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout,
- const sigset_t* mask) {
- if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- if (!__builtin_constant_p(fd_count)) {
- return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds));
- } else if (__bos(fds) / sizeof(*fds) < fd_count) {
- __ppoll_too_small_error();
- }
- }
- return __ppoll_real(fds, fd_count, timeout, mask);
-}
-
-#endif /* defined(__clang__) */
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/poll.h>
+#endif
__END_DECLS
-#endif /* _POLL_H_ */
+#endif
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 7dec3cc..32315fe 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -38,20 +38,15 @@
__BEGIN_DECLS
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
enum {
- PTHREAD_MUTEX_NORMAL = 0,
- PTHREAD_MUTEX_RECURSIVE = 1,
- PTHREAD_MUTEX_ERRORCHECK = 2,
+ PTHREAD_MUTEX_NORMAL = 0,
+ PTHREAD_MUTEX_RECURSIVE = 1,
+ PTHREAD_MUTEX_ERRORCHECK = 2,
- PTHREAD_MUTEX_ERRORCHECK_NP = PTHREAD_MUTEX_ERRORCHECK,
- PTHREAD_MUTEX_RECURSIVE_NP = PTHREAD_MUTEX_RECURSIVE,
+ PTHREAD_MUTEX_ERRORCHECK_NP = PTHREAD_MUTEX_ERRORCHECK,
+ PTHREAD_MUTEX_RECURSIVE_NP = PTHREAD_MUTEX_RECURSIVE,
- PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
+ PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
};
#define PTHREAD_MUTEX_INITIALIZER { { ((PTHREAD_MUTEX_NORMAL & 3) << 14) } }
@@ -88,79 +83,76 @@
#define PTHREAD_SCOPE_SYSTEM 0
#define PTHREAD_SCOPE_PROCESS 1
-int pthread_atfork(void (*)(void), void (*)(void), void (*)(void)) __INTRODUCED_IN(12);
+int pthread_atfork(void (*__prepare)(void), void (*__parent)(void), void (*__child)(void)) __INTRODUCED_IN(12);
-int pthread_attr_destroy(pthread_attr_t* _Nonnull);
-int pthread_attr_getdetachstate(const pthread_attr_t* _Nonnull, int* _Nonnull);
-int pthread_attr_getguardsize(const pthread_attr_t* _Nonnull, size_t* _Nonnull);
-int pthread_attr_getschedparam(const pthread_attr_t* _Nonnull, struct sched_param* _Nonnull);
-int pthread_attr_getschedpolicy(const pthread_attr_t* _Nonnull, int* _Nonnull);
-int pthread_attr_getscope(const pthread_attr_t* _Nonnull, int* _Nonnull);
-int pthread_attr_getstack(const pthread_attr_t* _Nonnull, void** _Nonnull, size_t* _Nonnull);
-int pthread_attr_getstacksize(const pthread_attr_t* _Nonnull, size_t* _Nonnull);
-int pthread_attr_init(pthread_attr_t* _Nonnull);
-int pthread_attr_setdetachstate(pthread_attr_t* _Nonnull, int);
-int pthread_attr_setguardsize(pthread_attr_t* _Nonnull, size_t);
-int pthread_attr_setschedparam(pthread_attr_t* _Nonnull, const struct sched_param* _Nonnull);
-int pthread_attr_setschedpolicy(pthread_attr_t* _Nonnull, int);
-int pthread_attr_setscope(pthread_attr_t* _Nonnull, int);
-int pthread_attr_setstack(pthread_attr_t* _Nonnull, void*, size_t);
-int pthread_attr_setstacksize(pthread_attr_t* _Nonnull, size_t);
+int pthread_attr_destroy(pthread_attr_t* __attr);
+int pthread_attr_getdetachstate(const pthread_attr_t* __attr, int* __state);
+int pthread_attr_getguardsize(const pthread_attr_t* __attr, size_t* __size);
+int pthread_attr_getschedparam(const pthread_attr_t* __attr, struct sched_param* __param);
+int pthread_attr_getschedpolicy(const pthread_attr_t* __attr, int* __policy);
+int pthread_attr_getscope(const pthread_attr_t* __attr, int* __scope);
+int pthread_attr_getstack(const pthread_attr_t* __attr, void** __addr, size_t* __size);
+int pthread_attr_getstacksize(const pthread_attr_t* __attr, size_t* __size);
+int pthread_attr_init(pthread_attr_t* __attr);
+int pthread_attr_setdetachstate(pthread_attr_t* __attr, int __state);
+int pthread_attr_setguardsize(pthread_attr_t* __attr, size_t __size);
+int pthread_attr_setschedparam(pthread_attr_t* __attr, const struct sched_param* __param);
+int pthread_attr_setschedpolicy(pthread_attr_t* __attr, int __policy);
+int pthread_attr_setscope(pthread_attr_t* __attr, int __scope);
+int pthread_attr_setstack(pthread_attr_t* __attr, void* __addr, size_t __size);
+int pthread_attr_setstacksize(pthread_attr_t* __addr, size_t __size);
-int pthread_condattr_destroy(pthread_condattr_t* _Nonnull);
-int pthread_condattr_getclock(const pthread_condattr_t* _Nonnull, clockid_t* _Nonnull)
+int pthread_condattr_destroy(pthread_condattr_t* __attr);
+int pthread_condattr_getclock(const pthread_condattr_t* __attr, clockid_t* __clock) __INTRODUCED_IN(21);
+int pthread_condattr_getpshared(const pthread_condattr_t* __attr, int* __shared);
+int pthread_condattr_init(pthread_condattr_t* __attr);
+int pthread_condattr_setclock(pthread_condattr_t* __attr, clockid_t __clock) __INTRODUCED_IN(21);
+int pthread_condattr_setpshared(pthread_condattr_t* __attr, int __shared);
+
+int pthread_cond_broadcast(pthread_cond_t* __cond);
+int pthread_cond_destroy(pthread_cond_t* __cond);
+int pthread_cond_init(pthread_cond_t* __cond, const pthread_condattr_t* __attr);
+int pthread_cond_signal(pthread_cond_t* __cond);
+int pthread_cond_timedwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const struct timespec* __timeout);
+int pthread_cond_wait(pthread_cond_t* __cond, pthread_mutex_t* __mutex);
+
+int pthread_create(pthread_t* __pthread_ptr, pthread_attr_t const* __attr, void* (*__start_routine)(void*), void*);
+int pthread_detach(pthread_t __pthread);
+void pthread_exit(void* __return_value) __noreturn;
+
+int pthread_equal(pthread_t __lhs, pthread_t __rhs);
+
+int pthread_getattr_np(pthread_t __pthread, pthread_attr_t* __attr);
+
+int pthread_getcpuclockid(pthread_t __pthread, clockid_t* __clock);
+
+int pthread_getschedparam(pthread_t __pthread, int* __policy, struct sched_param* __param);
+
+void* pthread_getspecific(pthread_key_t __key);
+
+pid_t pthread_gettid_np(pthread_t __pthread) __INTRODUCED_IN(21);
+
+int pthread_join(pthread_t __pthread, void** __return_value_ptr);
+
+int pthread_key_create(pthread_key_t* __key_ptr, void (*__key_destructor)(void*));
+int pthread_key_delete(pthread_key_t __key);
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t* __attr);
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t* __attr, int* __shared);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t* __attr, int* __type);
+int pthread_mutexattr_init(pthread_mutexattr_t* __attr);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t* __attr, int __shared);
+int pthread_mutexattr_settype(pthread_mutexattr_t* __attr, int __type);
+
+int pthread_mutex_destroy(pthread_mutex_t* __mutex);
+int pthread_mutex_init(pthread_mutex_t* __mutex, const pthread_mutexattr_t* __attr);
+int pthread_mutex_lock(pthread_mutex_t* __mutex);
+int pthread_mutex_timedlock(pthread_mutex_t* __mutex, const struct timespec* __timeout)
__INTRODUCED_IN(21);
-int pthread_condattr_getpshared(const pthread_condattr_t* _Nonnull, int* _Nonnull);
-int pthread_condattr_init(pthread_condattr_t* _Nonnull);
-int pthread_condattr_setclock(pthread_condattr_t* _Nonnull, clockid_t) __INTRODUCED_IN(21);
-int pthread_condattr_setpshared(pthread_condattr_t* _Nonnull, int);
+int pthread_mutex_trylock(pthread_mutex_t* __mutex);
+int pthread_mutex_unlock(pthread_mutex_t* __mutex);
-int pthread_cond_broadcast(pthread_cond_t* _Nonnull);
-int pthread_cond_destroy(pthread_cond_t* _Nonnull);
-int pthread_cond_init(pthread_cond_t* _Nonnull, const pthread_condattr_t*);
-int pthread_cond_signal(pthread_cond_t* _Nonnull);
-int pthread_cond_timedwait(pthread_cond_t* _Nonnull, pthread_mutex_t* _Nonnull,
- const struct timespec* _Nonnull);
-int pthread_cond_wait(pthread_cond_t* _Nonnull, pthread_mutex_t* _Nonnull);
-
-int pthread_create(pthread_t* _Nonnull, pthread_attr_t const*,
- void* (* _Nonnull start_routine)(void*), void*);
-int pthread_detach(pthread_t);
-void pthread_exit(void*) __noreturn;
-
-int pthread_equal(pthread_t, pthread_t);
-
-int pthread_getattr_np(pthread_t, pthread_attr_t* _Nonnull);
-
-int pthread_getcpuclockid(pthread_t, clockid_t* _Nonnull);
-
-int pthread_getschedparam(pthread_t, int* _Nonnull, struct sched_param* _Nonnull);
-
-void* pthread_getspecific(pthread_key_t);
-
-pid_t pthread_gettid_np(pthread_t) __INTRODUCED_IN(21);
-
-int pthread_join(pthread_t, void**);
-
-int pthread_key_create(pthread_key_t* _Nonnull, void (*)(void*));
-int pthread_key_delete(pthread_key_t);
-
-int pthread_mutexattr_destroy(pthread_mutexattr_t* _Nonnull);
-int pthread_mutexattr_getpshared(const pthread_mutexattr_t* _Nonnull, int* _Nonnull);
-int pthread_mutexattr_gettype(const pthread_mutexattr_t* _Nonnull, int* _Nonnull);
-int pthread_mutexattr_init(pthread_mutexattr_t* _Nonnull);
-int pthread_mutexattr_setpshared(pthread_mutexattr_t* _Nonnull, int);
-int pthread_mutexattr_settype(pthread_mutexattr_t* _Nonnull, int);
-
-int pthread_mutex_destroy(pthread_mutex_t* _Nonnull);
-int pthread_mutex_init(pthread_mutex_t* _Nonnull, const pthread_mutexattr_t*);
-int pthread_mutex_lock(pthread_mutex_t* _Nonnull);
-int pthread_mutex_timedlock(pthread_mutex_t* _Nonnull, const struct timespec* _Nonnull)
- __INTRODUCED_IN(21);
-int pthread_mutex_trylock(pthread_mutex_t* _Nonnull);
-int pthread_mutex_unlock(pthread_mutex_t* _Nonnull);
-
-#if defined(__LP32__) && __ANDROID_API__ < 21
+#if __ANDROID_API__ < 21
/*
* Cruft for supporting old API levels. Pre-L we didn't have the proper POSIX
* APIs for things, but instead had some locally grown, artisan equivalents.
@@ -172,69 +164,64 @@
* * https://github.com/android-ndk/ndk/issues/423
* * https://stackoverflow.com/q/44580542/632035
*/
-
-int pthread_mutex_lock_timeout_np(pthread_mutex_t* mutex, unsigned msecs);
-int pthread_cond_timeout_np(pthread_cond_t* cond, pthread_mutex_t* mutex, unsigned msecs);
-int pthread_cond_timedwait_monotonic_np(pthread_cond_t*, pthread_mutex_t*, const struct timespec*);
-int pthread_cond_timedwait_relative_np(pthread_cond_t* cond, pthread_mutex_t* mutex,
- const struct timespec* reltime);
+int pthread_mutex_lock_timeout_np(pthread_mutex_t* __mutex, unsigned __timeout_ms);
+int pthread_cond_timeout_np(pthread_cond_t* __cond, pthread_mutex_t* __mutex, unsigned __timeout_ms);
+int pthread_cond_timedwait_monotonic_np(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const struct timespec* __timeout);
+int pthread_cond_timedwait_relative_np(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const struct timespec* __relative_timeout);
#endif
-int pthread_once(pthread_once_t* _Nonnull, void (* _Nonnull init_routine)(void));
+int pthread_once(pthread_once_t* __once, void (*__init_routine)(void));
-int pthread_rwlockattr_init(pthread_rwlockattr_t* _Nonnull);
-int pthread_rwlockattr_destroy(pthread_rwlockattr_t* _Nonnull);
-int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* _Nonnull, int* _Nonnull);
-int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* _Nonnull, int);
-int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* _Nonnull, int* _Nonnull)
+int pthread_rwlockattr_init(pthread_rwlockattr_t* __attr);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t* __attr);
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* __attr, int* __shared);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* __attr, int __shared);
+int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* __attr, int* __kind)
__INTRODUCED_IN(23);
-int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* _Nonnull, int) __INTRODUCED_IN(23);
+int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* __attr, int __kind) __INTRODUCED_IN(23);
-int pthread_rwlock_destroy(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_init(pthread_rwlock_t* _Nonnull, const pthread_rwlockattr_t*);
-int pthread_rwlock_rdlock(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_timedrdlock(pthread_rwlock_t* _Nonnull, const struct timespec* _Nonnull);
-int pthread_rwlock_timedwrlock(pthread_rwlock_t* _Nonnull, const struct timespec* _Nonnull);
-int pthread_rwlock_tryrdlock(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_trywrlock(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_unlock(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_wrlock(pthread_rwlock_t* _Nonnull);
+int pthread_rwlock_destroy(pthread_rwlock_t* __rwlock);
+int pthread_rwlock_init(pthread_rwlock_t* __rwlock, const pthread_rwlockattr_t* __attr);
+int pthread_rwlock_rdlock(pthread_rwlock_t* __rwlock);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t* __rwlock, const struct timespec* __timeout);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t* __rwlock, const struct timespec* __timeout);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t* __rwlock);
+int pthread_rwlock_trywrlock(pthread_rwlock_t* __rwlock);
+int pthread_rwlock_unlock(pthread_rwlock_t* __rwlock);
+int pthread_rwlock_wrlock(pthread_rwlock_t* __rwlock);
#if __ANDROID_API__ >= __ANDROID_API_N__
-int pthread_barrierattr_init(pthread_barrierattr_t* _Nonnull attr) __INTRODUCED_IN(24);
-int pthread_barrierattr_destroy(pthread_barrierattr_t* _Nonnull attr) __INTRODUCED_IN(24);
-int pthread_barrierattr_getpshared(const pthread_barrierattr_t* _Nonnull attr,
- int* _Nonnull pshared) __INTRODUCED_IN(24);
-int pthread_barrierattr_setpshared(pthread_barrierattr_t* _Nonnull attr, int pshared)
- __INTRODUCED_IN(24);
+int pthread_barrierattr_init(pthread_barrierattr_t* __attr) __INTRODUCED_IN(24);
+int pthread_barrierattr_destroy(pthread_barrierattr_t* __attr) __INTRODUCED_IN(24);
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t* __attr, int* __shared) __INTRODUCED_IN(24);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t* __attr, int __shared) __INTRODUCED_IN(24);
#endif
#if __ANDROID_API__ >= __ANDROID_API_N__
-int pthread_barrier_init(pthread_barrier_t* _Nonnull, const pthread_barrierattr_t*, unsigned)
- __INTRODUCED_IN(24);
-int pthread_barrier_destroy(pthread_barrier_t* _Nonnull) __INTRODUCED_IN(24);
-int pthread_barrier_wait(pthread_barrier_t* _Nonnull) __INTRODUCED_IN(24);
+int pthread_barrier_init(pthread_barrier_t* __barrier, const pthread_barrierattr_t* __attr, unsigned __count) __INTRODUCED_IN(24);
+int pthread_barrier_destroy(pthread_barrier_t* __barrier) __INTRODUCED_IN(24);
+int pthread_barrier_wait(pthread_barrier_t* __barrier) __INTRODUCED_IN(24);
#endif
#if __ANDROID_API__ >= __ANDROID_API_N__
-int pthread_spin_destroy(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
-int pthread_spin_init(pthread_spinlock_t* _Nonnull, int) __INTRODUCED_IN(24);
-int pthread_spin_lock(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
-int pthread_spin_trylock(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
-int pthread_spin_unlock(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
+int pthread_spin_destroy(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_init(pthread_spinlock_t* __spinlock, int __shared) __INTRODUCED_IN(24);
+int pthread_spin_lock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_trylock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_unlock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
#endif
pthread_t pthread_self(void) __attribute_const__;
#if defined(__USE_GNU)
-int pthread_getname_np(pthread_t, char* _Nonnull, size_t) __INTRODUCED_IN(26);
+int pthread_getname_np(pthread_t __pthread, char* __buf, size_t __n) __INTRODUCED_IN(26);
#endif
/* TODO: this should be __USE_GNU too. */
-int pthread_setname_np(pthread_t, const char* _Nonnull);
+int pthread_setname_np(pthread_t __pthread, const char* __name);
-int pthread_setschedparam(pthread_t, int, const struct sched_param* _Nonnull);
+int pthread_setschedparam(pthread_t __pthread, int __policy, const struct sched_param* __param);
-int pthread_setspecific(pthread_key_t, const void*);
+int pthread_setspecific(pthread_key_t __key, const void* __value);
typedef void (*__pthread_cleanup_func_t)(void*);
@@ -262,10 +249,6 @@
__pthread_cleanup_pop( &__cleanup, (execute)); \
} while (0); \
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
__END_DECLS
-#endif /* _PTHREAD_H_ */
+#endif
diff --git a/libc/include/pty.h b/libc/include/pty.h
index ec257a5..cf9ccb9 100644
--- a/libc/include/pty.h
+++ b/libc/include/pty.h
@@ -36,9 +36,9 @@
__BEGIN_DECLS
-int openpty(int*, int*, char*, const struct termios*, const struct winsize*) __INTRODUCED_IN(23);
-int forkpty(int*, char*, const struct termios*, const struct winsize*) __INTRODUCED_IN(23);
+int openpty(int* __master_fd, int* __slave_fd, char* __slave_name, const struct termios* __termios_ptr, const struct winsize* __winsize_ptr) __INTRODUCED_IN(23);
+int forkpty(int* __master_fd, char* __slave_name, const struct termios* __termios_ptr, const struct winsize* __winsize_ptr) __INTRODUCED_IN(23);
__END_DECLS
-#endif /* _PTY_H */
+#endif
diff --git a/libc/include/pwd.h b/libc/include/pwd.h
index e37c637..5c516d7 100644
--- a/libc/include/pwd.h
+++ b/libc/include/pwd.h
@@ -80,8 +80,8 @@
char* pw_shell;
};
-struct passwd* getpwnam(const char*);
-struct passwd* getpwuid(uid_t);
+struct passwd* getpwnam(const char* __name);
+struct passwd* getpwuid(uid_t __uid);
/* Note: Android has thousands and thousands of ids to iterate through */
struct passwd* getpwent(void) __INTRODUCED_IN(26);
@@ -89,8 +89,8 @@
void setpwent(void) __INTRODUCED_IN(26);
void endpwent(void) __INTRODUCED_IN(26);
-int getpwnam_r(const char*, struct passwd*, char*, size_t, struct passwd**) __INTRODUCED_IN(12);
-int getpwuid_r(uid_t, struct passwd*, char*, size_t, struct passwd**) __INTRODUCED_IN(12);
+int getpwnam_r(const char* __name, struct passwd* __pwd, char* __buf, size_t __n, struct passwd** __result) __INTRODUCED_IN(12);
+int getpwuid_r(uid_t __uid, struct passwd* __pwd, char* __buf, size_t __n, struct passwd** __result) __INTRODUCED_IN(12);
__END_DECLS
diff --git a/libc/include/regex.h b/libc/include/regex.h
index b06a515..c4cc39c 100644
--- a/libc/include/regex.h
+++ b/libc/include/regex.h
@@ -97,10 +97,10 @@
#define REG_BACKR 02000 /* force use of backref code */
__BEGIN_DECLS
-int regcomp(regex_t *, const char *, int);
-size_t regerror(int, const regex_t *, char *, size_t);
-int regexec(const regex_t *, const char *, size_t, regmatch_t [], int);
-void regfree(regex_t *);
+int regcomp(regex_t* __re, const char* __regex, int __flags);
+size_t regerror(int __error_code, const regex_t* __re, char* __buf, size_t __n);
+int regexec(const regex_t* __re, const char* __s, size_t __match_count, regmatch_t __matches[], int __flags);
+void regfree(regex_t* __re);
__END_DECLS
-#endif /* !_REGEX_H_ */
+#endif
diff --git a/libc/include/resolv.h b/libc/include/resolv.h
index 2c12819..d6db4cf 100644
--- a/libc/include/resolv.h
+++ b/libc/include/resolv.h
@@ -40,25 +40,25 @@
__BEGIN_DECLS
#define b64_ntop __b64_ntop
-int b64_ntop(u_char const*, size_t, char*, size_t);
+int b64_ntop(u_char const* __src, size_t __src_size, char* __dst, size_t __dst_size);
#define b64_pton __b64_pton
-int b64_pton(char const*, u_char*, size_t);
+int b64_pton(char const* __src, u_char* __dst, size_t __dst_size);
#define dn_comp __dn_comp
-int dn_comp(const char*, u_char*, int, u_char**, u_char**);
+int dn_comp(const char* __src, u_char* __dst, int __dst_size, u_char** __dn_ptrs , u_char** __last_dn_ptr);
-int dn_expand(const u_char*, const u_char*, const u_char*, char*, int);
+int dn_expand(const u_char* __msg, const u_char* __eom, const u_char* __src, char* __dst, int __dst_size);
#define p_class __p_class
-const char* p_class(int);
+const char* p_class(int __class);
#define p_type __p_type
-const char* p_type(int);
+const char* p_type(int __type);
int res_init(void);
-int res_mkquery(int, const char*, int, int, const u_char*, int, const u_char*, u_char*, int);
-int res_query(const char*, int, int, u_char*, int);
-int res_search(const char*, int, int, u_char*, int);
+int res_mkquery(int __opcode, const char* __domain_name, int __class, int __type, const u_char* __data, int __data_size, const u_char* __new_rr_in, u_char* __buf, int __buf_size);
+int res_query(const char* __name, int __class, int __type, u_char* __answer, int __answer_size);
+int res_search(const char* __name, int __class, int __type, u_char* __answer, int __answer_size);
__END_DECLS
-#endif /* _RESOLV_H_ */
+#endif
diff --git a/libc/include/sched.h b/libc/include/sched.h
index d407202..de6969f8 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _SCHED_H_
#define _SCHED_H_
@@ -41,22 +42,22 @@
int sched_priority;
};
-int sched_setscheduler(pid_t, int, const struct sched_param*);
-int sched_getscheduler(pid_t);
+int sched_setscheduler(pid_t __pid, int __policy, const struct sched_param* __param);
+int sched_getscheduler(pid_t __pid);
int sched_yield(void);
-int sched_get_priority_max(int);
-int sched_get_priority_min(int);
-int sched_setparam(pid_t, const struct sched_param*);
-int sched_getparam(pid_t, struct sched_param*);
-int sched_rr_get_interval(pid_t, struct timespec*);
+int sched_get_priority_max(int __policy);
+int sched_get_priority_min(int __policy);
+int sched_setparam(pid_t __pid, const struct sched_param* __param);
+int sched_getparam(pid_t __pid, struct sched_param* __param);
+int sched_rr_get_interval(pid_t __pid, struct timespec* __quantum);
#if defined(__USE_GNU)
-int clone(int (*)(void*), void*, int, void*, ...) __INTRODUCED_IN_ARM(9)
- __INTRODUCED_IN_MIPS(12) __INTRODUCED_IN_X86(17);
-int unshare(int) __INTRODUCED_IN(17);
+int clone(int (*__fn)(void*), void* __child_stack, int __flags, void* __arg, ...)
+ __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_MIPS(12) __INTRODUCED_IN_X86(17);
+int unshare(int __flags) __INTRODUCED_IN(17);
int sched_getcpu(void) __INTRODUCED_IN(12);
-int setns(int, int) __INTRODUCED_IN(21);
+int setns(int __fd, int __ns_type) __INTRODUCED_IN(21);
#ifdef __LP64__
#define CPU_SETSIZE 1024
@@ -73,8 +74,8 @@
__CPU_BITTYPE __bits[ CPU_SETSIZE / __CPU_BITS ];
} cpu_set_t;
-int sched_setaffinity(pid_t pid, size_t setsize, const cpu_set_t* set) __INTRODUCED_IN(12);
-int sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set) __INTRODUCED_IN(12);
+int sched_setaffinity(pid_t __pid, size_t __set_size, const cpu_set_t* __set) __INTRODUCED_IN(12);
+int sched_getaffinity(pid_t __pid, size_t __set_size, cpu_set_t* __set) __INTRODUCED_IN(12);
#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t), set)
#define CPU_SET(cpu, set) CPU_SET_S(cpu, sizeof(cpu_set_t), set)
@@ -97,8 +98,8 @@
#define CPU_ALLOC(count) __sched_cpualloc((count))
#define CPU_FREE(set) __sched_cpufree((set))
-cpu_set_t* __sched_cpualloc(size_t count) __INTRODUCED_IN(12);
-void __sched_cpufree(cpu_set_t* set) __INTRODUCED_IN(12);
+cpu_set_t* __sched_cpualloc(size_t __count) __INTRODUCED_IN(12);
+void __sched_cpufree(cpu_set_t* __set) __INTRODUCED_IN(12);
#define CPU_ZERO_S(setsize, set) __builtin_memset(set, 0, setsize)
@@ -142,7 +143,7 @@
#define CPU_COUNT_S(setsize, set) __sched_cpucount((setsize), (set))
-int __sched_cpucount(size_t setsize, cpu_set_t* set) __INTRODUCED_IN(12);
+int __sched_cpucount(size_t __set_size, cpu_set_t* __set) __INTRODUCED_IN(12);
#endif /* __USE_GNU */
diff --git a/libc/include/search.h b/libc/include/search.h
index dc160e9..0015699 100644
--- a/libc/include/search.h
+++ b/libc/include/search.h
@@ -29,21 +29,20 @@
__BEGIN_DECLS
-void insque(void*, void*) __INTRODUCED_IN(21);
-void remque(void*) __INTRODUCED_IN(21);
+void insque(void* __element, void* __previous) __INTRODUCED_IN(21);
+void remque(void* __element) __INTRODUCED_IN(21);
-void* lfind(const void*, const void*, size_t*, size_t, int (*)(const void*, const void*))
+void* lfind(const void* __key, const void* __base, size_t* __count, size_t __size, int (*__comparator)(const void*, const void*))
__INTRODUCED_IN(21);
-void* lsearch(const void*, void*, size_t*, size_t, int (*)(const void*, const void*))
+void* lsearch(const void* __key, void* __base, size_t* __count, size_t __size, int (*__comparator)(const void*, const void*))
__INTRODUCED_IN(21);
-void* tdelete(const void* __restrict, void** __restrict, int (*)(const void*, const void*))
- __INTRODUCED_IN(16);
-void tdestroy(void*, void (*)(void*)) __INTRODUCED_IN(16);
-void* tfind(const void*, void* const*, int (*)(const void*, const void*)) __INTRODUCED_IN(16);
-void* tsearch(const void*, void**, int (*)(const void*, const void*)) __INTRODUCED_IN(16);
-void twalk(const void*, void (*)(const void*, VISIT, int)) __INTRODUCED_IN(21);
+void* tdelete(const void* __key, void** __root_ptr, int (*__comparator)(const void*, const void*)) __INTRODUCED_IN(16);
+void tdestroy(void* __root, void (*__free_fn)(void*)) __INTRODUCED_IN(16);
+void* tfind(const void* __key, void* const* __root_ptr, int (*__comparator)(const void*, const void*)) __INTRODUCED_IN(16);
+void* tsearch(const void* __key, void** __root_ptr, int (*__comparator)(const void*, const void*)) __INTRODUCED_IN(16);
+void twalk(const void* __root, void (*__visitor)(const void*, VISIT, int)) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* !_SEARCH_H_ */
+#endif
diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h
index 218f22a..7e3dc1c 100644
--- a/libc/include/semaphore.h
+++ b/libc/include/semaphore.h
@@ -44,19 +44,19 @@
#define SEM_FAILED __BIONIC_CAST(reinterpret_cast, sem_t*, 0)
-int sem_destroy(sem_t*);
-int sem_getvalue(sem_t*, int*);
-int sem_init(sem_t*, int, unsigned int);
-int sem_post(sem_t*);
-int sem_timedwait(sem_t*, const struct timespec*);
-int sem_trywait(sem_t*);
-int sem_wait(sem_t*);
+int sem_destroy(sem_t* __sem);
+int sem_getvalue(sem_t* __sem, int* __value);
+int sem_init(sem_t* __sem, int __shared, unsigned int __value);
+int sem_post(sem_t* __sem);
+int sem_timedwait(sem_t* __sem, const struct timespec* __ts);
+int sem_trywait(sem_t* __sem);
+int sem_wait(sem_t* __sem);
/* These aren't actually implemented. */
-sem_t* sem_open(const char*, int, ...);
-int sem_close(sem_t*);
-int sem_unlink(const char*);
+sem_t* sem_open(const char* __name, int _flags, ...);
+int sem_close(sem_t* __sem);
+int sem_unlink(const char* __name);
__END_DECLS
-#endif /* _SEMAPHORE_H */
+#endif
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index 7adeb35..12a3083 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -48,17 +48,17 @@
__BEGIN_DECLS
-int _setjmp(jmp_buf);
-void _longjmp(jmp_buf, int);
+int _setjmp(jmp_buf __env);
+void _longjmp(jmp_buf __env, int __value);
-int setjmp(jmp_buf);
-void longjmp(jmp_buf, int);
+int setjmp(jmp_buf __env);
+void longjmp(jmp_buf __env, int __value);
-int sigsetjmp(sigjmp_buf, int) __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_MIPS(12)
- __INTRODUCED_IN_X86(12);
-void siglongjmp(sigjmp_buf, int) __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_MIPS(12)
- __INTRODUCED_IN_X86(12);
+int sigsetjmp(sigjmp_buf __env, int __save_signal_mask)
+ __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_MIPS(12) __INTRODUCED_IN_X86(12);
+void siglongjmp(sigjmp_buf __env, int __value)
+ __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_MIPS(12) __INTRODUCED_IN_X86(12);
__END_DECLS
-#endif /* !_SETJMP_H_ */
+#endif
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 1400328..ece2916 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -54,11 +54,6 @@
__BEGIN_DECLS
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
typedef int sig_atomic_t;
/* The arm and x86 kernel header files don't define _NSIG. */
@@ -114,59 +109,55 @@
#endif
-int sigaction(int, const struct sigaction*, struct sigaction*);
+int sigaction(int __signal, const struct sigaction* __new_action, struct sigaction* __old_action);
-int siginterrupt(int, int);
+int siginterrupt(int __signal, int __flag);
#if __ANDROID_API__ >= __ANDROID_API_L__
-sighandler_t signal(int, sighandler_t) __INTRODUCED_IN(21);
-int sigaddset(sigset_t*, int) __INTRODUCED_IN(21);
-int sigdelset(sigset_t*, int) __INTRODUCED_IN(21);
-int sigemptyset(sigset_t*) __INTRODUCED_IN(21);
-int sigfillset(sigset_t*) __INTRODUCED_IN(21);
-int sigismember(const sigset_t*, int) __INTRODUCED_IN(21);
+sighandler_t signal(int __signal, sighandler_t __handler) __INTRODUCED_IN(21);
+int sigaddset(sigset_t* __set, int __signal) __INTRODUCED_IN(21);
+int sigdelset(sigset_t* __set, int __signal) __INTRODUCED_IN(21);
+int sigemptyset(sigset_t* __set) __INTRODUCED_IN(21);
+int sigfillset(sigset_t* __set) __INTRODUCED_IN(21);
+int sigismember(const sigset_t* __set, int __signal) __INTRODUCED_IN(21);
#else
// Implemented as static inlines before 21.
#endif
-int sigpending(sigset_t* _Nonnull);
-int sigprocmask(int, const sigset_t*, sigset_t*);
-int sigsuspend(const sigset_t* _Nonnull);
-int sigwait(const sigset_t* _Nonnull, int* _Nonnull);
+int sigpending(sigset_t* __set);
+int sigprocmask(int __how, const sigset_t* __new_set, sigset_t* __old_set);
+int sigsuspend(const sigset_t* __mask);
+int sigwait(const sigset_t* __set, int* __signal);
-int sighold(int)
+int sighold(int __signal)
__attribute__((deprecated("use sigprocmask() or pthread_sigmask() instead")))
__INTRODUCED_IN(26);
-int sigignore(int)
+int sigignore(int __signal)
__attribute__((deprecated("use sigaction() instead"))) __INTRODUCED_IN(26);
-int sigpause(int)
+int sigpause(int __signal)
__attribute__((deprecated("use sigsuspend() instead"))) __INTRODUCED_IN(26);
-int sigrelse(int)
+int sigrelse(int __signal)
__attribute__((deprecated("use sigprocmask() or pthread_sigmask() instead")))
__INTRODUCED_IN(26);
-sighandler_t sigset(int, sighandler_t)
+sighandler_t sigset(int __signal, sighandler_t __handler)
__attribute__((deprecated("use sigaction() instead"))) __INTRODUCED_IN(26);
-int raise(int);
-int kill(pid_t, int);
-int killpg(int, int);
-int tgkill(int tgid, int tid, int sig) __INTRODUCED_IN_32(16);
+int raise(int __signal);
+int kill(pid_t __pid, int __signal);
+int killpg(int __pgrp, int __signal);
+int tgkill(int __tgid, int __tid, int __signal) __INTRODUCED_IN_32(16);
-int sigaltstack(const stack_t*, stack_t*);
+int sigaltstack(const stack_t* __new_signal_stack, stack_t* __old_signal_stack);
-void psiginfo(const siginfo_t*, const char*) __INTRODUCED_IN(17);
-void psignal(int, const char*) __INTRODUCED_IN(17);
+void psiginfo(const siginfo_t* __info, const char* __msg) __INTRODUCED_IN(17);
+void psignal(int __signal, const char* __msg) __INTRODUCED_IN(17);
-int pthread_kill(pthread_t, int);
-int pthread_sigmask(int, const sigset_t*, sigset_t*);
+int pthread_kill(pthread_t __pthread, int __signal);
+int pthread_sigmask(int __how, const sigset_t* __new_set, sigset_t* __old_set);
-int sigqueue(pid_t, int, const union sigval) __INTRODUCED_IN(23);
-int sigtimedwait(const sigset_t* _Nonnull, siginfo_t*, const struct timespec*) __INTRODUCED_IN(23);
-int sigwaitinfo(const sigset_t* _Nonnull, siginfo_t*) __INTRODUCED_IN(23);
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
+int sigqueue(pid_t __pid, int __signal, const union sigval __value) __INTRODUCED_IN(23);
+int sigtimedwait(const sigset_t* __set, siginfo_t* __info, const struct timespec* __timeout) __INTRODUCED_IN(23);
+int sigwaitinfo(const sigset_t* __set, siginfo_t* __info) __INTRODUCED_IN(23);
__END_DECLS
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index ca56437..559e52a 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -44,9 +44,6 @@
#include <stdarg.h>
#include <stddef.h>
-#define __need_NULL
-#include <stddef.h>
-
#include <bits/seek_constants.h>
#if __ANDROID_API__ < __ANDROID_API_N__
@@ -55,11 +52,6 @@
__BEGIN_DECLS
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
typedef off_t fpos_t;
typedef off64_t fpos64_t;
@@ -105,424 +97,171 @@
* stdio can provide without attempting to allocate further resources
* (which could fail). Do not use this for anything.
*/
+#define FOPEN_MAX 20
+#define FILENAME_MAX 4096
-#define FOPEN_MAX 20 /* must be <= OPEN_MAX <sys/syslimits.h> */
-#define FILENAME_MAX 1024 /* must be <= PATH_MAX <sys/syslimits.h> */
+#define L_tmpnam 4096
+#define TMP_MAX 308915776
-#define L_tmpnam 1024 /* XXX must be == PATH_MAX */
-#define TMP_MAX 308915776
+void clearerr(FILE* __fp);
+int fclose(FILE* __fp);
+int feof(FILE* __fp);
+int ferror(FILE* __fp);
+int fflush(FILE* __fp);
+int fgetc(FILE* __fp);
+char* fgets(char* __buf, int __size, FILE* __fp) __overloadable __RENAME_CLANG(fgets);
+int fprintf(FILE* __fp , const char* __fmt, ...) __printflike(2, 3);
+int fputc(int __ch, FILE* __fp);
+int fputs(const char* __s, FILE* __fp);
+size_t fread(void* __buf, size_t __size, size_t __count, FILE* __fp) __overloadable __RENAME_CLANG(fread);
+int fscanf(FILE* __fp, const char* __fmt, ...) __scanflike(2, 3);
+size_t fwrite(const void* __buf, size_t __size, size_t __count, FILE* __fp) __overloadable __RENAME_CLANG(fwrite);
+int getc(FILE* __fp);
+int getchar(void);
+ssize_t getdelim(char** __line_ptr, size_t* __line_length_ptr, int __delimiter, FILE* __fp) __INTRODUCED_IN(18);
+ssize_t getline(char** __line_ptr, size_t* __line_length_ptr, FILE* __fp) __INTRODUCED_IN(18);
+void perror(const char* __msg);
+int printf(const char* __fmt, ...) __printflike(1, 2);
+int putc(int __ch, FILE* __fp);
+int putchar(int __ch);
+int puts(const char* __s);
+int remove(const char* __path);
+void rewind(FILE* __fp);
+int scanf(const char* __fmt, ...) __scanflike(1, 2);
+void setbuf(FILE* __fp, char* __buf);
+int setvbuf(FILE* __fp, char* __buf, int __mode, size_t __size);
+int sscanf(const char* __s, const char* __fmt, ...) __scanflike(2, 3);
+int ungetc(int __ch, FILE* __fp);
+int vfprintf(FILE* __fp, const char* __fmt, va_list __args) __printflike(2, 0);
+int vprintf(const char* __fp, va_list __args) __printflike(1, 0);
+
+#if __ANDROID_API__ >= 21
+int dprintf(int __fd, const char* __fmt, ...) __printflike(2, 3) __INTRODUCED_IN(21);
+int vdprintf(int __fd, const char* __fmt, va_list __args) __printflike(2, 0) __INTRODUCED_IN(21);
+#else
/*
- * Functions defined in ANSI C standard.
+ * Old versions of Android called these fdprintf and vfdprintf out of fears that the glibc names
+ * would collide with user debug printfs.
+ *
+ * Allow users to just use dprintf and vfdprintf on any version by renaming those calls to their
+ * legacy equivalents if needed.
*/
-void clearerr(FILE *);
-int fclose(FILE *);
-int feof(FILE *);
-int ferror(FILE *);
-int fflush(FILE *);
-int fgetc(FILE *);
-char *fgets(char * __restrict, int, FILE * __restrict) __overloadable
- __RENAME_CLANG(fgets);
-int fprintf(FILE * __restrict , const char * __restrict _Nonnull, ...) __printflike(2, 3);
-int fputc(int, FILE *);
-int fputs(const char * __restrict, FILE * __restrict);
-size_t fread(void * __restrict, size_t, size_t, FILE * __restrict)
- __overloadable __RENAME_CLANG(fread);
-int fscanf(FILE * __restrict, const char * __restrict _Nonnull, ...) __scanflike(2, 3);
-size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict)
- __overloadable __RENAME_CLANG(fwrite);
-int getc(FILE *);
-int getchar(void);
-ssize_t getdelim(char** __restrict, size_t* __restrict, int, FILE* __restrict) __INTRODUCED_IN(18);
-ssize_t getline(char** __restrict, size_t* __restrict, FILE* __restrict) __INTRODUCED_IN(18);
-
-void perror(const char *);
-int printf(const char * __restrict _Nonnull, ...) __printflike(1, 2);
-int putc(int, FILE *);
-int putchar(int);
-int puts(const char *);
-int remove(const char *);
-void rewind(FILE *);
-int scanf(const char * __restrict _Nonnull, ...) __scanflike(1, 2);
-void setbuf(FILE * __restrict, char * __restrict);
-int setvbuf(FILE * __restrict, char * __restrict, int, size_t);
-int sscanf(const char * __restrict, const char * __restrict _Nonnull, ...) __scanflike(2, 3);
-int ungetc(int, FILE *);
-int vfprintf(FILE * __restrict, const char * __restrict _Nonnull, __va_list) __printflike(2, 0);
-int vprintf(const char * __restrict _Nonnull, __va_list) __printflike(1, 0);
-
-int dprintf(int, const char* __restrict _Nonnull, ...) __printflike(2, 3) __INTRODUCED_IN(21);
-int vdprintf(int, const char* __restrict _Nonnull, __va_list) __printflike(2, 0) __INTRODUCED_IN(21);
+int dprintf(int __fd, const char* __fmt, ...) __RENAME(fdprintf) __printflike(2, 3);
+int vdprintf(int __fd, const char* __fmt, va_list __args) __RENAME(vfdprintf) __printflike(2, 0);
+#endif
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 201112L) || \
(defined(__cplusplus) && __cplusplus <= 201103L)
-char* gets(char*) __attribute__((deprecated("gets is unsafe, use fgets instead")));
+char* gets(char* __buf) __attribute__((deprecated("gets is unsafe, use fgets instead")));
#endif
-int sprintf(char* __restrict, const char* __restrict _Nonnull, ...)
+int sprintf(char* __s, const char* __fmt, ...)
__printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf")
__overloadable __RENAME_CLANG(sprintf);
-int vsprintf(char* __restrict, const char* __restrict _Nonnull, __va_list)
+int vsprintf(char* __s, const char* __fmt, va_list __args)
__overloadable __printflike(2, 0) __RENAME_CLANG(vsprintf)
__warnattr_strict("vsprintf is often misused; please use vsnprintf");
-char* tmpnam(char*)
+char* tmpnam(char* __s)
__warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
#define P_tmpdir "/tmp/" /* deprecated */
-char* tempnam(const char*, const char*)
+char* tempnam(const char* __dir, const char* __prefix)
__warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
-int rename(const char*, const char*);
-int renameat(int, const char*, int, const char*);
+int rename(const char* __old_path, const char* __new_path);
+int renameat(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path);
-int fseek(FILE*, long, int);
-long ftell(FILE*);
+int fseek(FILE* __fp, long __offset, int __whence);
+long ftell(FILE* __fp);
#if defined(__USE_FILE_OFFSET64)
-int fgetpos(FILE*, fpos_t*) __RENAME(fgetpos64) __INTRODUCED_IN(24);
-int fsetpos(FILE*, const fpos_t*) __RENAME(fsetpos64) __INTRODUCED_IN(24);
-int fseeko(FILE*, off_t, int) __RENAME(fseeko64) __INTRODUCED_IN(24);
-off_t ftello(FILE*) __RENAME(ftello64) __INTRODUCED_IN(24);
+int fgetpos(FILE* __fp, fpos_t* __pos) __RENAME(fgetpos64) __INTRODUCED_IN(24);
+int fsetpos(FILE* __fp, const fpos_t* __pos) __RENAME(fsetpos64) __INTRODUCED_IN(24);
+int fseeko(FILE* __fp, off_t __offset, int __whence) __RENAME(fseeko64) __INTRODUCED_IN(24);
+off_t ftello(FILE* __fp) __RENAME(ftello64) __INTRODUCED_IN(24);
# if defined(__USE_BSD)
-FILE* funopen(const void*,
- int (*)(void*, char*, int),
- int (*)(void*, const char*, int),
- fpos_t (*)(void*, fpos_t, int),
- int (*)(void*)) __RENAME(funopen64) __INTRODUCED_IN(24);
+FILE* funopen(const void* __cookie,
+ int (*__read_fn)(void*, char*, int),
+ int (*__write_fn)(void*, const char*, int),
+ fpos_t (*__seek_fn)(void*, fpos_t, int),
+ int (*__close_fn)(void*)) __RENAME(funopen64) __INTRODUCED_IN(24);
# endif
#else
-int fgetpos(FILE*, fpos_t*);
-int fsetpos(FILE*, const fpos_t*);
-int fseeko(FILE*, off_t, int);
-off_t ftello(FILE*);
+int fgetpos(FILE* __fp, fpos_t* __pos);
+int fsetpos(FILE* __fp, const fpos_t* __pos);
+int fseeko(FILE* __fp, off_t __offset, int __whence);
+off_t ftello(FILE* __fp);
# if defined(__USE_BSD)
-FILE* funopen(const void*,
- int (*)(void*, char*, int),
- int (*)(void*, const char*, int),
- fpos_t (*)(void*, fpos_t, int),
- int (*)(void*));
+FILE* funopen(const void* __cookie,
+ int (*__read_fn)(void*, char*, int),
+ int (*__write_fn)(void*, const char*, int),
+ fpos_t (*__seek_fn)(void*, fpos_t, int),
+ int (*__close_fn)(void*));
# endif
#endif
-int fgetpos64(FILE*, fpos64_t*) __INTRODUCED_IN(24);
-int fsetpos64(FILE*, const fpos64_t*) __INTRODUCED_IN(24);
-int fseeko64(FILE*, off64_t, int) __INTRODUCED_IN(24);
-off64_t ftello64(FILE*) __INTRODUCED_IN(24);
+int fgetpos64(FILE* __fp, fpos64_t* __pos) __INTRODUCED_IN(24);
+int fsetpos64(FILE* __fp, const fpos64_t* __pos) __INTRODUCED_IN(24);
+int fseeko64(FILE* __fp, off64_t __offset, int __whence) __INTRODUCED_IN(24);
+off64_t ftello64(FILE* __fp) __INTRODUCED_IN(24);
#if defined(__USE_BSD)
-FILE* funopen64(const void*, int (*)(void*, char*, int), int (*)(void*, const char*, int),
- fpos64_t (*)(void*, fpos64_t, int), int (*)(void*)) __INTRODUCED_IN(24);
+FILE* funopen64(const void* __cookie,
+ int (*__read_fn)(void*, char*, int),
+ int (*__write_fn)(void*, const char*, int),
+ fpos64_t (*__seek_fn)(void*, fpos64_t, int),
+ int (*__close_fn)(void*)) __INTRODUCED_IN(24);
#endif
-FILE* fopen(const char* __restrict, const char* __restrict);
-FILE* fopen64(const char* __restrict, const char* __restrict) __INTRODUCED_IN(24);
-FILE* freopen(const char* __restrict, const char* __restrict, FILE* __restrict);
-FILE* freopen64(const char* __restrict, const char* __restrict, FILE* __restrict)
- __INTRODUCED_IN(24);
+FILE* fopen(const char* __path, const char* __mode);
+FILE* fopen64(const char* __path, const char* __mode) __INTRODUCED_IN(24);
+FILE* freopen(const char* __path, const char* __mode, FILE* __fp);
+FILE* freopen64(const char* __path, const char* __mode, FILE* __fp) __INTRODUCED_IN(24);
FILE* tmpfile(void);
FILE* tmpfile64(void) __INTRODUCED_IN(24);
-int snprintf(char* __restrict, size_t, const char* __restrict _Nonnull, ...)
+int snprintf(char* __buf, size_t __size, const char* __fmt, ...)
__printflike(3, 4) __overloadable __RENAME_CLANG(snprintf);
-int vfscanf(FILE* __restrict, const char* __restrict _Nonnull, __va_list) __scanflike(2, 0);
-int vscanf(const char* _Nonnull , __va_list) __scanflike(1, 0);
-int vsnprintf(char* __restrict, size_t, const char* __restrict _Nonnull, __va_list)
+int vfscanf(FILE* __fp, const char* __fmt, va_list __args) __scanflike(2, 0);
+int vscanf(const char* __fmt , va_list __args) __scanflike(1, 0);
+int vsnprintf(char* __buf, size_t __size, const char* __fmt, va_list __args)
__printflike(3, 0) __overloadable __RENAME_CLANG(vsnprintf);
-int vsscanf(const char* __restrict _Nonnull, const char* __restrict _Nonnull, __va_list) __scanflike(2, 0);
+int vsscanf(const char* __s, const char* __fmt, va_list __args) __scanflike(2, 0);
#define L_ctermid 1024 /* size for ctermid() */
-char* ctermid(char*) __INTRODUCED_IN(26);
+char* ctermid(char* __buf) __INTRODUCED_IN(26);
-FILE* fdopen(int, const char*);
-int fileno(FILE*);
-int pclose(FILE*);
-FILE* popen(const char*, const char*);
-void flockfile(FILE*);
-int ftrylockfile(FILE*);
-void funlockfile(FILE*);
-int getc_unlocked(FILE*);
+FILE* fdopen(int __fd, const char* __mode);
+int fileno(FILE* __fp);
+int pclose(FILE* __fp);
+FILE* popen(const char* __command, const char* __mode);
+void flockfile(FILE* __fp);
+int ftrylockfile(FILE* __fp);
+void funlockfile(FILE* __fp);
+int getc_unlocked(FILE* __fp);
int getchar_unlocked(void);
-int putc_unlocked(int, FILE*);
-int putchar_unlocked(int);
+int putc_unlocked(int __ch, FILE* __fp);
+int putchar_unlocked(int __ch);
-FILE* fmemopen(void*, size_t, const char*) __INTRODUCED_IN(23);
-FILE* open_memstream(char**, size_t*) __INTRODUCED_IN(23);
+FILE* fmemopen(void* __buf, size_t __size, const char* __mode) __INTRODUCED_IN(23);
+FILE* open_memstream(char** __ptr, size_t* __size_ptr) __INTRODUCED_IN(23);
#if defined(__USE_BSD) || defined(__BIONIC__) /* Historically bionic exposed these. */
-int asprintf(char** __restrict, const char* __restrict _Nonnull, ...) __printflike(2, 3);
-char* fgetln(FILE* __restrict, size_t* __restrict);
-int fpurge(FILE*);
-void setbuffer(FILE*, char*, int);
-int setlinebuf(FILE*);
-int vasprintf(char** __restrict, const char* __restrict _Nonnull, __va_list) __printflike(2, 0);
-void clearerr_unlocked(FILE*) __INTRODUCED_IN(23);
-int feof_unlocked(FILE*) __INTRODUCED_IN(23);
-int ferror_unlocked(FILE*) __INTRODUCED_IN(23);
-int fileno_unlocked(FILE*) __INTRODUCED_IN(24);
+int asprintf(char** __s_ptr, const char* __fmt, ...) __printflike(2, 3);
+char* fgetln(FILE* __fp, size_t* __length_ptr);
+int fpurge(FILE* __fp);
+void setbuffer(FILE* __fp, char* __buf, int __size);
+int setlinebuf(FILE* __fp);
+int vasprintf(char** __s_ptr, const char* __fmt, va_list __args) __printflike(2, 0);
+void clearerr_unlocked(FILE* __fp) __INTRODUCED_IN(23);
+int feof_unlocked(FILE* __fp) __INTRODUCED_IN(23);
+int ferror_unlocked(FILE* __fp) __INTRODUCED_IN(23);
+int fileno_unlocked(FILE* __fp) __INTRODUCED_IN(24);
#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
#endif /* __USE_BSD */
-char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
-size_t __fread_chk(void* __restrict, size_t, size_t, FILE* __restrict, size_t)
- __INTRODUCED_IN(24);
-size_t __fwrite_chk(const void* __restrict, size_t, size_t, FILE* __restrict, size_t)
- __INTRODUCED_IN(24);
-
-#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE __printflike(3, 0)
-int vsnprintf(char *const __pass_object_size dest, size_t size,
- const char *_Nonnull format, __va_list ap) __overloadable {
- return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
-}
-
-__BIONIC_FORTIFY_INLINE __printflike(2, 0)
-int vsprintf(char *const __pass_object_size dest, const char *_Nonnull format,
- __va_list ap) __overloadable {
- return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if defined(__clang__)
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-/*
- * Simple case: `format` can't have format specifiers, so we can just compare
- * its length to the length of `dest`
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int snprintf(char *__restrict dest, size_t size, const char *__restrict format)
- __overloadable
- __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(dest) < __builtin_strlen(format),
- "format string will always overflow destination buffer")
- __errorattr("format string will always overflow destination buffer");
-
-__BIONIC_FORTIFY_INLINE
-__printflike(3, 4)
-int snprintf(char *__restrict const __pass_object_size dest,
- size_t size, const char *__restrict format, ...) __overloadable {
- va_list va;
- va_start(va, format);
- int result = __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, va);
- va_end(va);
- return result;
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int sprintf(char *__restrict dest, const char *__restrict format) __overloadable
- __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(dest) < __builtin_strlen(format),
- "format string will always overflow destination buffer")
- __errorattr("format string will always overflow destination buffer");
-
-__BIONIC_FORTIFY_INLINE
-__printflike(2, 3)
-int sprintf(char *__restrict const __pass_object_size dest,
- const char *__restrict format, ...) __overloadable {
- va_list va;
- va_start(va, format);
- int result = __builtin___vsprintf_chk(dest, 0, __bos(dest), format, va);
- va_end(va);
- return result;
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict buf, size_t size, size_t count,
- FILE *__restrict stream) __overloadable
- __enable_if(__unsafe_check_mul_overflow(size, count), "size * count overflows")
- __errorattr("size * count overflows");
-
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict buf, size_t size, size_t count,
- FILE *__restrict stream) __overloadable
- __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
- __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- size * count > __bos(buf), "size * count is too large")
- __errorattr("size * count is too large");
-
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict const __pass_object_size0 buf, size_t size,
- size_t count, FILE *__restrict stream) __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(fread)(buf, size, count, stream);
- }
-
- return __fread_chk(buf, size, count, stream, bos);
-}
-
-size_t fwrite(const void * __restrict buf, size_t size,
- size_t count, FILE * __restrict stream) __overloadable
- __enable_if(__unsafe_check_mul_overflow(size, count),
- "size * count overflows")
- __errorattr("size * count overflows");
-
-size_t fwrite(const void * __restrict buf, size_t size,
- size_t count, FILE * __restrict stream) __overloadable
- __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
- __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- size * count > __bos(buf), "size * count is too large")
- __errorattr("size * count is too large");
-
-__BIONIC_FORTIFY_INLINE
-size_t fwrite(const void * __restrict const __pass_object_size0 buf,
- size_t size, size_t count, FILE * __restrict stream)
- __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
- }
-
- return __fwrite_chk(buf, size, count, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char *fgets(char* __restrict dest, int size, FILE* stream) __overloadable
- __enable_if(size < 0, "size is negative")
- __errorattr("size is negative");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char *fgets(char* dest, int size, FILE* stream) __overloadable
- __enable_if(size >= 0 && size > __bos(dest),
- "size is larger than the destination buffer")
- __errorattr("size is larger than the destination buffer");
-
-__BIONIC_FORTIFY_INLINE
-char *fgets(char* __restrict const __pass_object_size dest,
- int size, FILE* stream) __overloadable {
- size_t bos = __bos(dest);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(fgets)(dest, size, stream);
- }
-
- return __fgets_chk(dest, size, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#else /* defined(__clang__) */
-
-size_t __fread_real(void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fread);
-__errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
-__errordecl(__fread_overflow, "fread called with overflowing size * count");
-
-char* __fgets_real(char*, int, FILE*) __RENAME(fgets);
-__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
-__errordecl(__fgets_too_small_error, "fgets called with size less than zero");
-
-size_t __fwrite_real(const void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fwrite);
-__errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer");
-__errordecl(__fwrite_overflow, "fwrite called with overflowing size * count");
-
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE __printflike(3, 4)
-int snprintf(char *__restrict dest, size_t size, const char* _Nonnull format, ...)
-{
- return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format,
- __builtin_va_arg_pack());
-}
-
-__BIONIC_FORTIFY_INLINE __printflike(2, 3)
-int sprintf(char *__restrict dest, const char* _Nonnull format, ...) {
- return __builtin___sprintf_chk(dest, 0, __bos(dest), format,
- __builtin_va_arg_pack());
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict buf, size_t size, size_t count, FILE * __restrict stream) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __fread_real(buf, size, count, stream);
- }
-
- if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
- size_t total;
- if (__size_mul_overflow(size, count, &total)) {
- __fread_overflow();
- }
-
- if (total > bos) {
- __fread_too_big_error();
- }
-
- return __fread_real(buf, size, count, stream);
- }
-
- return __fread_chk(buf, size, count, stream, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __fwrite_real(buf, size, count, stream);
- }
-
- if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
- size_t total;
- if (__size_mul_overflow(size, count, &total)) {
- __fwrite_overflow();
- }
-
- if (total > bos) {
- __fwrite_too_big_error();
- }
-
- return __fwrite_real(buf, size, count, stream);
- }
-
- return __fwrite_chk(buf, size, count, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-char *fgets(char* dest, int size, FILE* stream) {
- size_t bos = __bos(dest);
-
- // Compiler can prove, at compile time, that the passed in size
- // is always negative. Force a compiler error.
- if (__builtin_constant_p(size) && (size < 0)) {
- __fgets_too_small_error();
- }
-
- // Compiler doesn't know destination size. Don't call __fgets_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __fgets_real(dest, size, stream);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always <= the actual object size. Don't call __fgets_chk
- if (__builtin_constant_p(size) && (size <= (int) bos)) {
- return __fgets_real(dest, size, stream);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always > the actual object size. Force a compiler error.
- if (__builtin_constant_p(size) && (size > (int) bos)) {
- __fgets_too_big_error();
- }
-
- return __fgets_chk(dest, size, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#endif /* defined(__clang__) */
-#endif /* defined(__BIONIC_FORTIFY) */
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stdio.h>
#endif
__END_DECLS
-#endif /* _STDIO_H_ */
+#endif
diff --git a/libc/include/stdio_ext.h b/libc/include/stdio_ext.h
index fdf6772..66a3ab9 100644
--- a/libc/include/stdio_ext.h
+++ b/libc/include/stdio_ext.h
@@ -32,20 +32,23 @@
#include <sys/cdefs.h>
#include <stdio.h>
-#define FSETLOCKING_QUERY 0
-#define FSETLOCKING_INTERNAL 1
-#define FSETLOCKING_BYCALLER 2
__BEGIN_DECLS
-size_t __fbufsize(FILE*) __INTRODUCED_IN(23);
-int __freadable(FILE*) __INTRODUCED_IN(23);
-int __fwritable(FILE*) __INTRODUCED_IN(23);
-int __flbf(FILE*) __INTRODUCED_IN(23);
-void __fpurge(FILE*) __INTRODUCED_IN(23);
-size_t __fpending(FILE*) __INTRODUCED_IN(23);
+size_t __fbufsize(FILE* __fp) __INTRODUCED_IN(23);
+int __freadable(FILE* __fp) __INTRODUCED_IN(23);
+int __freading(FILE* __fp) __INTRODUCED_IN_FUTURE;
+int __fwritable(FILE* __fp) __INTRODUCED_IN(23);
+int __fwriting(FILE* __fp) __INTRODUCED_IN_FUTURE;
+int __flbf(FILE* __fp) __INTRODUCED_IN(23);
+void __fpurge(FILE* __fp) __INTRODUCED_IN(23);
+size_t __fpending(FILE* __fp) __INTRODUCED_IN(23);
void _flushlbf(void) __INTRODUCED_IN(23);
-int __fsetlocking(FILE*, int) __INTRODUCED_IN(23);
+
+#define FSETLOCKING_QUERY 0
+#define FSETLOCKING_INTERNAL 1
+#define FSETLOCKING_BYCALLER 2
+int __fsetlocking(FILE* __fp, int __type) __INTRODUCED_IN(23);
__END_DECLS
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 24ddd99..4182f2d 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -42,116 +42,114 @@
#define EXIT_SUCCESS 0
__noreturn void abort(void);
-__noreturn void exit(int);
-__noreturn void _Exit(int) __INTRODUCED_IN(21);
-int atexit(void (*)(void));
+__noreturn void exit(int __status);
+__noreturn void _Exit(int __status) __INTRODUCED_IN(21);
+int atexit(void (*__fn)(void));
-int at_quick_exit(void (*)(void)) __INTRODUCED_IN(21);
-void quick_exit(int) __noreturn __INTRODUCED_IN(21);
+int at_quick_exit(void (*__fn)(void)) __INTRODUCED_IN(21);
+void quick_exit(int __status) __noreturn __INTRODUCED_IN(21);
-char* getenv(const char*);
-int putenv(char*);
-int setenv(const char*, const char*, int);
-int unsetenv(const char*);
+char* getenv(const char* __name);
+int putenv(char* __assignment);
+int setenv(const char* __name, const char* __value, int __overwrite);
+int unsetenv(const char* __name);
int clearenv(void);
-char* mkdtemp(char*);
-char* mktemp(char*) __attribute__((deprecated("mktemp is unsafe, use mkstemp or tmpfile instead")));
+char* mkdtemp(char* __template);
+char* mktemp(char* __template) __attribute__((deprecated("mktemp is unsafe, use mkstemp or tmpfile instead")));
-int mkostemp64(char*, int) __INTRODUCED_IN(23);
-int mkostemp(char*, int) __INTRODUCED_IN(23);
-int mkostemps64(char*, int, int) __INTRODUCED_IN(23);
-int mkostemps(char*, int, int) __INTRODUCED_IN(23);
-int mkstemp64(char*) __INTRODUCED_IN(21);
-int mkstemp(char*);
-int mkstemps64(char*, int) __INTRODUCED_IN(23);
-int mkstemps(char*, int);
+int mkostemp64(char* __template, int __flags) __INTRODUCED_IN(23);
+int mkostemp(char* __template, int __flags) __INTRODUCED_IN(23);
+int mkostemps64(char* __template, int __suffix_length, int __flags) __INTRODUCED_IN(23);
+int mkostemps(char* __template, int __suffix_length, int __flags) __INTRODUCED_IN(23);
+int mkstemp64(char* __template) __INTRODUCED_IN(21);
+int mkstemp(char* __template);
+int mkstemps64(char* __template, int __flags) __INTRODUCED_IN(23);
+int mkstemps(char* __template, int __flags);
-long strtol(const char *, char **, int);
-long long strtoll(const char *, char **, int);
-unsigned long strtoul(const char *, char **, int);
-unsigned long long strtoull(const char *, char **, int);
+long strtol(const char* __s, char** __end_ptr, int __base);
+long long strtoll(const char* __s, char** __end_ptr, int __base);
+unsigned long strtoul(const char* __s, char** __end_ptr, int __base);
+unsigned long long strtoull(const char* __s, char** __end_ptr, int __base);
-int posix_memalign(void** memptr, size_t alignment, size_t size) __INTRODUCED_IN(16);
+int posix_memalign(void** __memptr, size_t __alignment, size_t __size) __INTRODUCED_IN(16);
-double strtod(const char*, char**);
-long double strtold(const char*, char**) __INTRODUCED_IN(21);
+double strtod(const char* __s, char** __end_ptr);
+long double strtold(const char* __s, char** __end_ptr) __INTRODUCED_IN(21);
-unsigned long strtoul_l(const char*, char**, int, locale_t) __INTRODUCED_IN(26);
+unsigned long strtoul_l(const char* __s, char** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(26);
-int atoi(const char*) __attribute_pure__;
-long atol(const char*) __attribute_pure__;
-long long atoll(const char*) __attribute_pure__;
+int atoi(const char* __s) __attribute_pure__;
+long atol(const char* __s) __attribute_pure__;
+long long atoll(const char* __s) __attribute_pure__;
-char * realpath(const char *path, char *resolved) __overloadable
- __RENAME_CLANG(realpath);
-int system(const char *string);
+char* realpath(const char* __path, char* __resolved);
+int system(const char* __command);
-void* bsearch(const void* key, const void* base0, size_t nmemb, size_t size,
- int (*compar)(const void*, const void*));
+void* bsearch(const void* __key, const void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs));
-void qsort(void*, size_t, size_t, int (*)(const void*, const void*));
+void qsort(void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs));
uint32_t arc4random(void);
-uint32_t arc4random_uniform(uint32_t);
-void arc4random_buf(void*, size_t);
+uint32_t arc4random_uniform(uint32_t __upper_bound);
+void arc4random_buf(void* __buf, size_t __n);
#define RAND_MAX 0x7fffffff
-int rand_r(unsigned int*) __INTRODUCED_IN(21);
+int rand_r(unsigned int* __seed_ptr) __INTRODUCED_IN(21);
double drand48(void);
-double erand48(unsigned short[3]);
-long jrand48(unsigned short[3]);
-void lcong48(unsigned short[7]) __INTRODUCED_IN(23);
+double erand48(unsigned short __xsubi[3]);
+long jrand48(unsigned short __xsubi[3]);
+void lcong48(unsigned short __param[7]) __INTRODUCED_IN(23);
long lrand48(void);
long mrand48(void);
-long nrand48(unsigned short[3]);
-unsigned short* seed48(unsigned short[3]);
-void srand48(long);
+long nrand48(unsigned short __xsubi[3]);
+unsigned short* seed48(unsigned short __seed16v[3]);
+void srand48(long __seed);
-char* initstate(unsigned int, char*, size_t) __INTRODUCED_IN(21);
-char* setstate(char*) __INTRODUCED_IN(21);
+char* initstate(unsigned int __seed, char* __state, size_t __n) __INTRODUCED_IN(21);
+char* setstate(char* __state) __INTRODUCED_IN(21);
int getpt(void);
-int posix_openpt(int) __INTRODUCED_IN(21);
-char* ptsname(int);
-int ptsname_r(int, char*, size_t);
-int unlockpt(int);
+int posix_openpt(int __flags) __INTRODUCED_IN(21);
+char* ptsname(int __fd);
+int ptsname_r(int __fd, char* __buf, size_t __n);
+int unlockpt(int __fd);
-int getsubopt(char**, char* const*, char**) __INTRODUCED_IN(26);
+int getsubopt(char** __option, char* const* __tokens, char** __value_ptr) __INTRODUCED_IN(26);
typedef struct {
- int quot;
- int rem;
+ int quot;
+ int rem;
} div_t;
-div_t div(int, int) __attribute_const__;
+div_t div(int __numerator, int __denominator) __attribute_const__;
typedef struct {
- long int quot;
- long int rem;
+ long int quot;
+ long int rem;
} ldiv_t;
-ldiv_t ldiv(long, long) __attribute_const__;
+ldiv_t ldiv(long __numerator, long __denominator) __attribute_const__;
typedef struct {
- long long int quot;
- long long int rem;
+ long long int quot;
+ long long int rem;
} lldiv_t;
-lldiv_t lldiv(long long, long long) __attribute_const__;
+lldiv_t lldiv(long long __numerator, long long __denominator) __attribute_const__;
/* BSD compatibility. */
const char* getprogname(void) __INTRODUCED_IN(21);
-void setprogname(const char*) __INTRODUCED_IN(21);
+void setprogname(const char* __name) __INTRODUCED_IN(21);
-int mblen(const char*, size_t) __INTRODUCED_IN(26) __VERSIONER_NO_GUARD;
-size_t mbstowcs(wchar_t*, const char*, size_t);
-int mbtowc(wchar_t*, const char*, size_t) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;
-int wctomb(char*, wchar_t) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;
+int mblen(const char* __s, size_t __n) __INTRODUCED_IN(26) __VERSIONER_NO_GUARD;
+size_t mbstowcs(wchar_t* __dst, const char* __src, size_t __n);
+int mbtowc(wchar_t* __wc_ptr, const char* __s, size_t __n) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;
+int wctomb(char* __dst, wchar_t __wc) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;
-size_t wcstombs(char*, const wchar_t*, size_t);
+size_t wcstombs(char* __dst, const wchar_t* __src, size_t __n);
#if __ANDROID_API__ >= __ANDROID_API_L__
size_t __ctype_get_mb_cur_max(void) __INTRODUCED_IN(21);
@@ -165,70 +163,33 @@
#define MB_CUR_MAX 1
#endif
-#if defined(__BIONIC_FORTIFY)
-#define __realpath_buf_too_small_str \
- "realpath output parameter must be NULL or a >= PATH_MAX bytes buffer"
-
-/* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
-#define __PATH_MAX 4096
-
-#if defined(__clang__)
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char* realpath(const char* path, char* resolved) __overloadable
- __enable_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(resolved) < __PATH_MAX, __realpath_buf_too_small_str)
- __errorattr(__realpath_buf_too_small_str);
-
-/* No need for a FORTIFY version; the only things we can catch are at
- * compile-time.
- */
-
-#else /* defined(__clang__) */
-
-char* __realpath_real(const char*, char*) __RENAME(realpath);
-__errordecl(__realpath_size_error, __realpath_buf_too_small_str);
-
-__BIONIC_FORTIFY_INLINE
-char* realpath(const char* path, char* resolved) {
- size_t bos = __bos(resolved);
-
- if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) {
- __realpath_size_error();
- }
-
- return __realpath_real(path, resolved);
-}
-
-#endif /* defined(__clang__) */
-
-#undef __PATH_MAX
-#undef __realpath_buf_too_small_str
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stdlib.h>
+#endif
#if __ANDROID_API__ >= __ANDROID_API_L__
-float strtof(const char*, char**) __INTRODUCED_IN(21);
-double atof(const char*) __attribute_pure__ __INTRODUCED_IN(21);
-int abs(int) __attribute_const__ __INTRODUCED_IN(21);
-long labs(long) __attribute_const__ __INTRODUCED_IN(21);
-long long llabs(long long) __attribute_const__ __INTRODUCED_IN(21);
+float strtof(const char* __s, char** __end_ptr) __INTRODUCED_IN(21);
+double atof(const char* __s) __attribute_pure__ __INTRODUCED_IN(21);
+int abs(int __x) __attribute_const__ __INTRODUCED_IN(21);
+long labs(long __x) __attribute_const__ __INTRODUCED_IN(21);
+long long llabs(long long __x) __attribute_const__ __INTRODUCED_IN(21);
int rand(void) __INTRODUCED_IN(21);
-void srand(unsigned int) __INTRODUCED_IN(21);
+void srand(unsigned int __seed) __INTRODUCED_IN(21);
long random(void) __INTRODUCED_IN(21);
-void srandom(unsigned int) __INTRODUCED_IN(21);
-int grantpt(int) __INTRODUCED_IN(21);
+void srandom(unsigned int __seed) __INTRODUCED_IN(21);
+int grantpt(int __fd) __INTRODUCED_IN(21);
-long long strtoll_l(const char*, char**, int, locale_t) __INTRODUCED_IN(21);
-unsigned long long strtoull_l(const char*, char**, int, locale_t) __INTRODUCED_IN(21);
-long double strtold_l(const char*, char**, locale_t) __INTRODUCED_IN(21);
+long long strtoll_l(const char* __s, char** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
+unsigned long long strtoull_l(const char* __s, char** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
+long double strtold_l(const char* __s, char** __end_ptr, locale_t __l) __INTRODUCED_IN(21);
#else
// Implemented as static inlines before 21.
#endif
#if __ANDROID_API__ >= __ANDROID_API_O__
-double strtod_l(const char*, char**, locale_t) __INTRODUCED_IN(26);
-float strtof_l(const char*, char**, locale_t) __INTRODUCED_IN(26);
-long strtol_l(const char*, char**, int, locale_t) __INTRODUCED_IN(26);
+double strtod_l(const char* __s, char** __end_ptr, locale_t __l) __INTRODUCED_IN(26);
+float strtof_l(const char* __s, char** __end_ptr, locale_t __l) __INTRODUCED_IN(26);
+long strtol_l(const char* __s, char** __end_ptr, int, locale_t __l) __INTRODUCED_IN(26);
#else
// Implemented as static inlines before 26.
#endif
diff --git a/libc/include/string.h b/libc/include/string.h
index c15fe4a..d409ba8 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -37,101 +37,95 @@
__BEGIN_DECLS
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
#if defined(__USE_BSD)
#include <strings.h>
#endif
-void* memccpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, int, size_t);
-void* memchr(const void* _Nonnull, int, size_t) __attribute_pure__ __overloadable
- __RENAME_CLANG(memchr);
-void* memrchr(const void* _Nonnull, int, size_t) __attribute_pure__ __overloadable
- __RENAME_CLANG(memrchr);
-int memcmp(const void* _Nonnull, const void* _Nonnull, size_t) __attribute_pure__;
-void* memcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t)
+void* memccpy(void* __dst, const void* __src, int __stop_char, size_t __n);
+void* memchr(const void* __s, int __ch, size_t __n) __attribute_pure__ __overloadable __RENAME_CLANG(memchr);
+#if defined(__cplusplus)
+extern "C++" void* memrchr(void* __s, int __ch, size_t __n) __RENAME(memrchr) __attribute_pure__;
+extern "C++" const void* memrchr(const void* __s, int __ch, size_t __n) __RENAME(memrchr) __attribute_pure__;
+#else
+void* memrchr(const void* __s, int __ch, size_t __n) __attribute_pure__ __overloadable __RENAME_CLANG(memrchr);
+#endif
+int memcmp(const void* __lhs, const void* __rhs, size_t __n) __attribute_pure__;
+void* memcpy(void*, const void*, size_t)
__overloadable __RENAME_CLANG(memcpy);
#if defined(__USE_GNU)
-void* mempcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t) __INTRODUCED_IN(23);
+void* mempcpy(void* __dst, const void* __src, size_t __n) __INTRODUCED_IN(23);
#endif
-void* memmove(void* _Nonnull, const void* _Nonnull, size_t) __overloadable
- __RENAME_CLANG(memmove);
-void* memset(void* _Nonnull, int, size_t) __overloadable __RENAME_CLANG(memset);
-void* memmem(const void* _Nonnull, size_t, const void* _Nonnull, size_t) __attribute_pure__;
+void* memmove(void* __dst, const void* __src, size_t __n) __overloadable __RENAME_CLANG(memmove);
+void* memset(void* __dst, int __ch, size_t __n) __overloadable __RENAME_CLANG(memset);
+void* memmem(const void* __haystack, size_t __haystack_size, const void* __needle, size_t __needle_size) __attribute_pure__;
-char* strchr(const char* _Nonnull, int) __attribute_pure__ __overloadable
- __RENAME_CLANG(strchr);
-char* __strchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18);
+char* strchr(const char* __s, int __ch) __attribute_pure__ __overloadable __RENAME_CLANG(strchr);
+char* __strchr_chk(const char* __s, int __ch, size_t __n) __INTRODUCED_IN(18);
#if defined(__USE_GNU)
#if defined(__cplusplus)
-extern "C++" char* strchrnul(char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
-extern "C++" const char* strchrnul(const char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
+/* The versioner doesn't handle C++ blocks yet, so manually guarded. */
+#if __ANDROID_API__ >= 24
+extern "C++" char* strchrnul(char* __s, int __ch) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
+extern "C++" const char* strchrnul(const char* __s, int __ch) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
#else
-char* strchrnul(const char* _Nonnull, int) __attribute_pure__ __INTRODUCED_IN(24);
+char* strchrnul(const char* __s, int __ch) __attribute_pure__ __INTRODUCED_IN(24);
#endif
#endif
-char* strrchr(const char* _Nonnull, int) __attribute_pure__ __overloadable
- __RENAME_CLANG(strrchr);
-char* __strrchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18);
+char* strrchr(const char* __s, int __ch) __attribute_pure__ __overloadable __RENAME_CLANG(strrchr);
+char* __strrchr_chk(const char* __s, int __ch, size_t __n) __INTRODUCED_IN(18);
-size_t strlen(const char* _Nonnull) __attribute_pure__ __overloadable
- __RENAME_CLANG(strlen);
-size_t __strlen_chk(const char* _Nonnull, size_t) __INTRODUCED_IN(17);
+size_t strlen(const char* __s) __attribute_pure__ __overloadable __RENAME_CLANG(strlen);
+size_t __strlen_chk(const char* __s, size_t __n) __INTRODUCED_IN(17);
-int strcmp(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-char* stpcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict)
- __overloadable __RENAME_CLANG(stpcpy) __INTRODUCED_IN(21);
-char* strcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict)
- __overloadable __RENAME_CLANG(strcpy);
-char* strcat(char* _Nonnull __restrict, const char* _Nonnull __restrict)
- __overloadable __RENAME_CLANG(strcat);
-char* strdup(const char* _Nonnull);
+int strcmp(const char* __lhs, const char* __rhs) __attribute_pure__;
+char* stpcpy(char* __dst, const char* __src) __overloadable __RENAME_CLANG(stpcpy) __INTRODUCED_IN(21);
+char* strcpy(char* __dst, const char* __src) __overloadable __RENAME_CLANG(strcpy);
+char* strcat(char* __dst, const char* __src) __overloadable __RENAME_CLANG(strcat);
+char* strdup(const char* __s);
-char* strstr(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-char* strcasestr(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-char* strtok(char* __restrict, const char* _Nonnull __restrict);
-char* strtok_r(char* __restrict, const char* _Nonnull __restrict, char** _Nonnull __restrict);
+char* strstr(const char* __haystack, const char* __needle) __attribute_pure__;
+#if defined(__cplusplus)
+extern "C++" char* strcasestr(char*, const char*) __RENAME(strcasestr) __attribute_pure__;
+extern "C++" const char* strcasestr(const char*, const char*) __RENAME(strcasestr) __attribute_pure__;
+#else
+char* strcasestr(const char* __haystack, const char* __needle) __attribute_pure__;
+#endif
+char* strtok(char* __s, const char* __delimiter);
+char* strtok_r(char* __s, const char* __delimiter, char** __pos_ptr);
-char* strerror(int);
-char* strerror_l(int, locale_t) __INTRODUCED_IN(23);
+char* strerror(int __errno_value);
+char* strerror_l(int __errno_value, locale_t __l) __INTRODUCED_IN(23);
#if defined(__USE_GNU) && __ANDROID_API__ >= 23
-char* strerror_r(int, char*, size_t) __RENAME(__gnu_strerror_r) __INTRODUCED_IN(23);
+char* strerror_r(int __errno_value, char* __buf, size_t __n) __RENAME(__gnu_strerror_r) __INTRODUCED_IN(23);
#else /* POSIX */
-int strerror_r(int, char*, size_t);
+int strerror_r(int __errno_value, char* __buf, size_t __n);
#endif
-size_t strnlen(const char* _Nonnull, size_t) __attribute_pure__;
-char* strncat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
- __overloadable __RENAME_CLANG(strncat);
-char* strndup(const char* _Nonnull, size_t);
-int strncmp(const char* _Nonnull, const char* _Nonnull, size_t) __attribute_pure__;
-char* stpncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
- __overloadable __RENAME_CLANG(stpncpy) __INTRODUCED_IN(21);
-char* strncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
- __overloadable __RENAME_CLANG(strncpy);
+size_t strnlen(const char* __s, size_t __n) __attribute_pure__;
+char* strncat(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(strncat);
+char* strndup(const char* __s, size_t __n);
+int strncmp(const char* __lhs, const char* __rhs, size_t __n) __attribute_pure__;
+char* stpncpy(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(stpncpy) __INTRODUCED_IN(21);
+char* strncpy(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(strncpy);
-size_t strlcat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
- __overloadable __RENAME_CLANG(strlcat);
-size_t strlcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
- __overloadable __RENAME_CLANG(strlcpy);
+size_t strlcat(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(strlcat);
+size_t strlcpy(char* __dst, const char* __src, size_t __n) __overloadable __RENAME_CLANG(strlcpy);
-size_t strcspn(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-char* strpbrk(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-char* strsep(char** _Nonnull __restrict, const char* _Nonnull __restrict);
-size_t strspn(const char* _Nonnull, const char* _Nonnull);
+size_t strcspn(const char* __s, const char* __reject) __attribute_pure__;
+char* strpbrk(const char* __s, const char* __accept) __attribute_pure__;
+char* strsep(char** __s_ptr, const char* __delimiter);
+size_t strspn(const char* __s, const char* __accept);
-char* strsignal(int);
+char* strsignal(int __signal);
-int strcoll(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-size_t strxfrm(char* __restrict, const char* _Nonnull __restrict, size_t);
+int strcoll(const char* __lhs, const char* __rhs) __attribute_pure__;
+size_t strxfrm(char* __dst, const char* __src, size_t __n);
#if __ANDROID_API__ >= __ANDROID_API_L__
-int strcoll_l(const char* _Nonnull, const char* _Nonnull, locale_t) __attribute_pure__ __INTRODUCED_IN(21);
-size_t strxfrm_l(char* __restrict, const char* _Nonnull __restrict, size_t, locale_t) __INTRODUCED_IN(21);
+int strcoll_l(const char* __lhs, const char* __rhs, locale_t __l) __attribute_pure__ __INTRODUCED_IN(21);
+size_t strxfrm_l(char* __dst, const char* __src, size_t __n, locale_t __l) __INTRODUCED_IN(21);
#else
// Implemented as static inlines before 21.
#endif
@@ -142,462 +136,19 @@
* It doesn't modify its argument, and in C++ it's const-correct.
*/
#if defined(__cplusplus)
-extern "C++" char* basename(char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
-extern "C++" const char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+/* The versioner doesn't handle C++ blocks yet, so manually guarded. */
+#if __ANDROID_API__ >= 23
+extern "C++" char* basename(char* __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+extern "C++" const char* basename(const char* __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+#endif /* __ANDROID_API__ >= 23 */
#else
-char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+char* basename(const char* __path) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
#endif
#endif
-void* __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
-void* __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
-char* __stpncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
- __INTRODUCED_IN(21);
-char* __strncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
- __INTRODUCED_IN(21);
-size_t __strlcpy_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
-size_t __strlcat_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
-
-/* Only used with FORTIFY, but some headers that need it undef FORTIFY, so we
- * have the definition out here.
- */
-struct __bionic_zero_size_is_okay_t {};
-
-#if defined(__BIONIC_FORTIFY)
-// These can share their implementation between gcc and clang with minimal
-// trickery...
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-void* memcpy(void* _Nonnull __restrict const dst __pass_object_size0, const void* _Nonnull __restrict src, size_t copy_amount)
- __overloadable {
- return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memmove(void* const _Nonnull dst __pass_object_size0, const void* _Nonnull src, size_t len)
- __overloadable {
- return __builtin___memmove_chk(dst, src, len, __bos0(dst));
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_FORTIFY_INLINE
-char* stpcpy(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
- __overloadable {
- return __builtin___stpcpy_chk(dst, src, __bos(dst));
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-char* strcpy(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
- __overloadable {
- return __builtin___strcpy_chk(dst, src, __bos(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strcat(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
- __overloadable {
- return __builtin___strcat_chk(dst, src, __bos(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strncat(char* const _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t n)
- __overloadable {
- return __builtin___strncat_chk(dst, src, n, __bos(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n) __overloadable {
- return __builtin___memset_chk(s, c, n, __bos0(s));
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-
-#if defined(__clang__)
-
-#define __error_if_overflows_dst(name, dst, n, what) \
- __enable_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
- __bos0(dst) < (n), "selected when the buffer is too small") \
- __errorattr(#name " called with " what " bigger than buffer")
-
-/*
- * N.B. _Nonnull isn't necessary on params, since these functions just emit
- * errors.
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memcpy(void* dst, const void* src, size_t copy_amount) __overloadable
- __error_if_overflows_dst(memcpy, dst, copy_amount, "size");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memmove(void *dst, const void* src, size_t len) __overloadable
- __error_if_overflows_dst(memmove, dst, len, "size");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memset(void* s, int c, size_t n) __overloadable
- __error_if_overflows_dst(memset, s, n, "size");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char* stpcpy(char* dst, const char* src) __overloadable
- __error_if_overflows_dst(stpcpy, dst, __builtin_strlen(src), "string");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char* strcpy(char* dst, const char* src) __overloadable
- __error_if_overflows_dst(strcpy, dst, __builtin_strlen(src), "string");
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_FORTIFY_INLINE
-void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
- __overloadable {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_memchr(s, c, n);
- }
-
- return __memchr_chk(s, c, n, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
- __overloadable {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(memrchr)(s, c, n);
- }
-
- return __memrchr_chk(s, c, n, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_FORTIFY_INLINE
-char* stpncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
- __overloadable {
- size_t bos_dst = __bos(dst);
- size_t bos_src = __bos(src);
-
- /* Ignore dst size checks; they're handled in strncpy_chk */
- if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin___stpncpy_chk(dst, src, n, bos_dst);
- }
-
- return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
- __overloadable {
- size_t bos_dst = __bos(dst);
- size_t bos_src = __bos(src);
-
- /* Ignore dst size checks; they're handled in strncpy_chk */
- if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin___strncpy_chk(dst, src, n, bos_dst);
- }
-
- return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-size_t strlcpy(char* const _Nonnull __restrict dst __pass_object_size, const char *_Nonnull __restrict src, size_t size)
- __overloadable {
- size_t bos = __bos(dst);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(strlcpy)(dst, src, size);
- }
-
- return __strlcpy_chk(dst, src, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlcat(char* const _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size)
- __overloadable {
- size_t bos = __bos(dst);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(strlcat)(dst, src, size);
- }
-
- return __strlcat_chk(dst, src, size, bos);
-}
-
-/*
- * If we can evaluate the size of s at compile-time, just call __builtin_strlen
- * on it directly. This makes it way easier for compilers to fold things like
- * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
- * because it's large.
- */
-__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* const _Nonnull s __pass_object_size)
- __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
- "enabled if s is a known good string.") {
- return __builtin_strlen(s);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* const _Nonnull s __pass_object_size0)
- __overloadable {
- size_t bos = __bos0(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strlen(s);
- }
-
- // return __builtin_strlen(s);
- return __strlen_chk(s, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
-__BIONIC_FORTIFY_INLINE
-char* strchr(const char* const _Nonnull s __pass_object_size, int c)
- __overloadable {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strchr(s, c);
- }
-
- return __strchr_chk(s, c, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strrchr(const char* const _Nonnull s __pass_object_size, int c)
- __overloadable {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strrchr(s, c);
- }
-
- return __strrchr_chk(s, c, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-/* In *many* cases, memset(foo, sizeof(foo), 0) is a mistake where the user has
- * flipped the size + value arguments. However, there may be cases (e.g. with
- * macros) where it's okay for the size to fold to zero. We should warn on this,
- * but we should also provide a FORTIFY'ed escape hatch.
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memset(void* _Nonnull s, int c, size_t n, struct __bionic_zero_size_is_okay_t ok)
- __overloadable
- __error_if_overflows_dst(memset, s, n, "size");
-
-__BIONIC_FORTIFY_INLINE
-void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n, struct __bionic_zero_size_is_okay_t ok __attribute__((unused)))
- __overloadable {
- return __builtin___memset_chk(s, c, n, __bos0(s));
-}
-
-extern struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
-/* We verify that `c` is non-zero, because as pointless as memset(foo, 0, 0) is,
- * flipping size + count will do nothing.
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memset(void* _Nonnull s, int c, size_t n) __overloadable
- __enable_if(c && !n, "selected when we'll set zero bytes")
- __RENAME_CLANG(memset)
- __warnattr_real("will set 0 bytes; maybe the arguments got flipped? "
- "(Add __bionic_zero_size_is_okay as a fourth argument "
- "to silence this.)");
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#undef __error_zero_size
-#undef __error_if_overflows_dst
-#else // defined(__clang__)
-extern char* __strncpy_real(char* __restrict, const char*, size_t) __RENAME(strncpy);
-extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
-extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
- __RENAME(strlcpy);
-extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
- __RENAME(strlcat);
-
-__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
-__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_FORTIFY_INLINE
-void* memchr(const void *_Nonnull s __pass_object_size, int c, size_t n) {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_memchr(s, c, n);
- }
-
- if (__builtin_constant_p(n) && (n > bos)) {
- __memchr_buf_size_error();
- }
-
- if (__builtin_constant_p(n) && (n <= bos)) {
- return __builtin_memchr(s, c, n);
- }
-
- return __memchr_chk(s, c, n, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* s, int c, size_t n) {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __memrchr_real(s, c, n);
- }
-
- if (__builtin_constant_p(n) && (n > bos)) {
- __memrchr_buf_size_error();
- }
-
- if (__builtin_constant_p(n) && (n <= bos)) {
- return __memrchr_real(s, c, n);
- }
-
- return __memrchr_chk(s, c, n, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_FORTIFY_INLINE
-char* stpncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
- size_t bos_dst = __bos(dst);
- size_t bos_src = __bos(src);
-
- if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin___stpncpy_chk(dst, src, n, bos_dst);
- }
-
- if (__builtin_constant_p(n) && (n <= bos_src)) {
- return __builtin___stpncpy_chk(dst, src, n, bos_dst);
- }
-
- size_t slen = __builtin_strlen(src);
- if (__builtin_constant_p(slen)) {
- return __builtin___stpncpy_chk(dst, src, n, bos_dst);
- }
-
- return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
- size_t bos_dst = __bos(dst);
- size_t bos_src = __bos(src);
-
- if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __strncpy_real(dst, src, n);
- }
-
- if (__builtin_constant_p(n) && (n <= bos_src)) {
- return __builtin___strncpy_chk(dst, src, n, bos_dst);
- }
-
- size_t slen = __builtin_strlen(src);
- if (__builtin_constant_p(slen)) {
- return __builtin___strncpy_chk(dst, src, n, bos_dst);
- }
-
- return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-size_t strlcpy(char* _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size) {
- size_t bos = __bos(dst);
-
- // Compiler doesn't know destination size. Don't call __strlcpy_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __strlcpy_real(dst, src, size);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always <= the actual object size. Don't call __strlcpy_chk
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __strlcpy_real(dst, src, size);
- }
-
- return __strlcpy_chk(dst, src, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t size) {
- size_t bos = __bos(dst);
-
- // Compiler doesn't know destination size. Don't call __strlcat_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __strlcat_real(dst, src, size);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always <= the actual object size. Don't call __strlcat_chk
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __strlcat_real(dst, src, size);
- }
-
- return __strlcat_chk(dst, src, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* _Nonnull s) __overloadable {
- size_t bos = __bos(s);
-
- // Compiler doesn't know destination size. Don't call __strlen_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strlen(s);
- }
-
- size_t slen = __builtin_strlen(s);
- if (__builtin_constant_p(slen)) {
- return slen;
- }
-
- return __strlen_chk(s, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
-__BIONIC_FORTIFY_INLINE
-char* strchr(const char* _Nonnull s, int c) {
- size_t bos = __bos(s);
-
- // Compiler doesn't know destination size. Don't call __strchr_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strchr(s, c);
- }
-
- size_t slen = __builtin_strlen(s);
- if (__builtin_constant_p(slen) && (slen < bos)) {
- return __builtin_strchr(s, c);
- }
-
- return __strchr_chk(s, c, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strrchr(const char* _Nonnull s, int c) {
- size_t bos = __bos(s);
-
- // Compiler doesn't know destination size. Don't call __strrchr_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strrchr(s, c);
- }
-
- size_t slen = __builtin_strlen(s);
- if (__builtin_constant_p(slen) && (slen < bos)) {
- return __builtin_strrchr(s, c);
- }
-
- return __strrchr_chk(s, c, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-#endif /* defined(__clang__) */
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/string.h>
+#endif
/* Const-correct overloads. Placed after FORTIFY so we call those functions, if possible. */
#if defined(__cplusplus) && defined(__clang__)
@@ -608,87 +159,83 @@
#define __prefer_this_overload __enable_if(true, "preferred overload") __enable_if(true, "")
extern "C++" {
inline __always_inline
-void* __bionic_memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n) {
+void* __bionic_memchr(const void* const s __pass_object_size, int c, size_t n) {
return memchr(s, c, n);
}
inline __always_inline
-const void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
+const void* memchr(const void* const s __pass_object_size, int c, size_t n)
__prefer_this_overload {
return __bionic_memchr(s, c, n);
}
inline __always_inline
-void* memchr(void* const _Nonnull s __pass_object_size, int c, size_t n) __prefer_this_overload {
+void* memchr(void* const s __pass_object_size, int c, size_t n) __prefer_this_overload {
return __bionic_memchr(s, c, n);
}
inline __always_inline
-char* __bionic_strchr(const char* const _Nonnull s __pass_object_size, int c) {
+char* __bionic_strchr(const char* const s __pass_object_size, int c) {
return strchr(s, c);
}
inline __always_inline
-const char* strchr(const char* const _Nonnull s __pass_object_size, int c)
+const char* strchr(const char* const s __pass_object_size, int c)
__prefer_this_overload {
return __bionic_strchr(s, c);
}
inline __always_inline
-char* strchr(char* const _Nonnull s __pass_object_size, int c)
+char* strchr(char* const s __pass_object_size, int c)
__prefer_this_overload {
return __bionic_strchr(s, c);
}
inline __always_inline
-char* __bionic_strrchr(const char* const _Nonnull s __pass_object_size, int c) {
+char* __bionic_strrchr(const char* const s __pass_object_size, int c) {
return strrchr(s, c);
}
inline __always_inline
-const char* strrchr(const char* const _Nonnull s __pass_object_size, int c) __prefer_this_overload {
+const char* strrchr(const char* const s __pass_object_size, int c) __prefer_this_overload {
return __bionic_strrchr(s, c);
}
inline __always_inline
-char* strrchr(char* const _Nonnull s __pass_object_size, int c) __prefer_this_overload {
+char* strrchr(char* const s __pass_object_size, int c) __prefer_this_overload {
return __bionic_strrchr(s, c);
}
/* Functions with no FORTIFY counterpart. */
inline __always_inline
-char* __bionic_strstr(const char* _Nonnull h, const char* _Nonnull n) { return strstr(h, n); }
+char* __bionic_strstr(const char* h, const char* n) { return strstr(h, n); }
inline __always_inline
-const char* strstr(const char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
+const char* strstr(const char* h, const char* n) __prefer_this_overload {
return __bionic_strstr(h, n);
}
inline __always_inline
-char* strstr(char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
+char* strstr(char* h, const char* n) __prefer_this_overload {
return __bionic_strstr(h, n);
}
inline __always_inline
-char* __bionic_strpbrk(const char* _Nonnull h, const char* _Nonnull n) { return strpbrk(h, n); }
+char* __bionic_strpbrk(const char* h, const char* n) { return strpbrk(h, n); }
inline __always_inline
-char* strpbrk(char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
+char* strpbrk(char* h, const char* n) __prefer_this_overload {
return __bionic_strpbrk(h, n);
}
inline __always_inline
-const char* strpbrk(const char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
+const char* strpbrk(const char* h, const char* n) __prefer_this_overload {
return __bionic_strpbrk(h, n);
}
}
#undef __prefer_this_overload
#endif
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
__END_DECLS
-#endif /* _STRING_H */
+#endif
diff --git a/libc/include/strings.h b/libc/include/strings.h
index 11f3213..c2e0a5e 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -55,11 +55,11 @@
#endif
#if !defined(__i386__) || __ANDROID_API__ >= __ANDROID_API_J_MR2__
-int ffs(int) __INTRODUCED_IN_X86(18);
+int ffs(int __i) __INTRODUCED_IN_X86(18);
#endif
__END_DECLS
#include <android/legacy_strings_inlines.h>
-#endif /* !defined(_STRINGS_H_) */
+#endif
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index f8dbd33..67beb9a 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -61,14 +61,14 @@
** Map the property area from the specified filename. This
** method is for testing only.
*/
-int __system_property_set_filename(const char *filename);
+int __system_property_set_filename(const char* __filename);
/*
** Initialize the area to be used to store properties. Can
** only be done by a single process that has write access to
** the property area.
*/
-int __system_property_area_init();
+int __system_property_area_init(void);
/* Read the global serial number of the system properties
**
@@ -92,7 +92,7 @@
**
** Returns the serial number on success, -1 on error.
*/
-uint32_t __system_property_area_serial();
+uint32_t __system_property_area_serial(void);
/* Add a new system property. Can only be done by a single
** process that has write access to the property area, and
@@ -102,7 +102,7 @@
**
** Returns 0 on success, -1 if the property area is full.
*/
-int __system_property_add(const char *name, unsigned int namelen, const char *value, unsigned int valuelen);
+int __system_property_add(const char* __name, unsigned int __name_length, const char* __value, unsigned int __value_length);
/* Update the value of a system property returned by
** __system_property_find. Can only be done by a single process
@@ -112,14 +112,14 @@
**
** Returns 0 on success, -1 if the parameters are incorrect.
*/
-int __system_property_update(prop_info *pi, const char *value, unsigned int len);
+int __system_property_update(prop_info* __pi, const char* __value, unsigned int __value_length);
/* Read the serial number of a system property returned by
** __system_property_find.
**
** Returns the serial number on success, -1 on error.
*/
-uint32_t __system_property_serial(const prop_info* pi);
+uint32_t __system_property_serial(const prop_info* __pi);
/* Initialize the system properties area in read only mode.
* Should be done by all processes that need to read system
@@ -127,10 +127,10 @@
*
* Returns 0 on success, -1 otherwise.
*/
-int __system_properties_init();
+int __system_properties_init(void);
/* Deprecated: use __system_property_wait instead. */
-uint32_t __system_property_wait_any(uint32_t old_serial);
+uint32_t __system_property_wait_any(uint32_t __old_serial);
__END_DECLS
diff --git a/libc/include/sys/auxv.h b/libc/include/sys/auxv.h
index ab5a39d..9251390 100644
--- a/libc/include/sys/auxv.h
+++ b/libc/include/sys/auxv.h
@@ -35,8 +35,8 @@
__BEGIN_DECLS
-unsigned long int getauxval(unsigned long int type) __INTRODUCED_IN(18);
+unsigned long int getauxval(unsigned long int __type) __INTRODUCED_IN(18);
__END_DECLS
-#endif /* _SYS_AUXV_H_ */
+#endif
diff --git a/libc/include/sys/cachectl.h b/libc/include/sys/cachectl.h
index 5b20c19..9235327 100644
--- a/libc/include/sys/cachectl.h
+++ b/libc/include/sys/cachectl.h
@@ -34,4 +34,4 @@
#include <asm/cachectl.h>
#endif
-#endif /* sys/cachectl.h */
+#endif
diff --git a/libc/include/sys/capability.h b/libc/include/sys/capability.h
index b9a40b3..637c844 100644
--- a/libc/include/sys/capability.h
+++ b/libc/include/sys/capability.h
@@ -34,9 +34,9 @@
__BEGIN_DECLS
-int capget(cap_user_header_t hdrp, cap_user_data_t datap);
-int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
+int capget(cap_user_header_t __hdr_ptr, cap_user_data_t __data_ptr);
+int capset(cap_user_header_t __hdr_ptr, const cap_user_data_t __data_ptr);
__END_DECLS
-#endif /* _BIONIC_SYS_CAPABILITY_H */
+#endif
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index d62206d..58eebc5 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -111,39 +111,6 @@
#define __unused __attribute__((__unused__))
#define __used __attribute__((__used__))
-/*
- * _Nonnull is similar to the nonnull attribute in that it will instruct
- * compilers to warn the user if it can prove that a null argument is being
- * passed. Unlike the nonnull attribute, this annotation indicated that a value
- * *should not* be null, not that it *cannot* be null, or even that the behavior
- * is undefined. The important distinction is that the optimizer will perform
- * surprising optimizations like the following:
- *
- * void foo(void*) __attribute__(nonnull, 1);
- *
- * int bar(int* p) {
- * foo(p);
- *
- * // The following null check will be elided because nonnull attribute
- * // means that, since we call foo with p, p can be assumed to not be
- * // null. Thus this will crash if we are called with a null pointer.
- * if (p != NULL) {
- * return *p;
- * }
- * return 0;
- * }
- *
- * int main() {
- * return bar(NULL);
- * }
- *
- * http://clang.llvm.org/docs/AttributeReference.html#nonnull
- */
-#if !(defined(__clang__) && __has_feature(nullability))
-#define _Nonnull
-#define _Nullable
-#endif
-
#define __printflike(x, y) __attribute__((__format__(printf, x, y)))
#define __scanflike(x, y) __attribute__((__format__(scanf, x, y)))
@@ -185,11 +152,16 @@
# define __warnattr(msg) __attribute__((deprecated(msg)))
# define __warnattr_real(msg) __attribute__((deprecated(msg)))
# define __enable_if(cond, msg) __attribute__((enable_if(cond, msg)))
+# define __clang_error_if(cond, msg) __attribute__((diagnose_if(cond, msg, "error")))
+# define __clang_warning_if(cond, msg) __attribute__((diagnose_if(cond, msg, "warning")))
#else
# define __errorattr(msg) __attribute__((__error__(msg)))
# define __warnattr(msg) __attribute__((__warning__(msg)))
# define __warnattr_real __warnattr
/* enable_if doesn't exist on other compilers; give an error if it's used. */
+/* diagnose_if doesn't exist either, but it's often tagged on non-clang-specific functions */
+# define __clang_error_if(cond, msg)
+# define __clang_warning_if(cond, msg)
/* errordecls really don't work as well in clang as they do in GCC. */
# define __errordecl(name, msg) extern void name(void) __errorattr(msg)
@@ -235,10 +207,16 @@
#endif
/* _FILE_OFFSET_BITS 64 support. */
-#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS)
-#if _FILE_OFFSET_BITS == 64
+#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
#define __USE_FILE_OFFSET64 1
-#endif
+/*
+ * Note that __RENAME_IF_FILE_OFFSET64 is only valid if the off_t and off64_t
+ * functions were both added at the same API level because if you use this,
+ * you only have one declaration to attach __INTRODUCED_IN to.
+ */
+#define __RENAME_IF_FILE_OFFSET64(func) __RENAME(func)
+#else
+#define __RENAME_IF_FILE_OFFSET64(func)
#endif
#define __BIONIC__ 1
@@ -261,8 +239,18 @@
#define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1)
-#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
-# define __BIONIC_FORTIFY 1
+#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
+# if defined(__clang__)
+/* FORTIFY's _chk functions effectively disable ASAN's stdlib interceptors. */
+# if !__has_feature(address_sanitizer)
+# define __BIONIC_FORTIFY 1
+# endif
+# elif defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
+# define __BIONIC_FORTIFY 1
+# endif
+#endif
+
+#if defined(__BIONIC_FORTIFY)
# if _FORTIFY_SOURCE == 2
# define __bos_level 1
# else
@@ -303,6 +291,10 @@
#define __pass_object_size __pass_object_size_n(__bos_level)
#define __pass_object_size0 __pass_object_size_n(0)
+#if defined(__BIONIC_FORTIFY) || defined(__BIONIC_DECLARE_FORTIFY_HELPERS)
+# define __BIONIC_INCLUDE_FORTIFY_HEADERS 1
+#endif
+
/*
* Used to support clangisms with FORTIFY. Because these change how symbols are
* emitted, we need to ensure that bionic itself is built fortified. But lots
diff --git a/libc/include/sys/endian.h b/libc/include/sys/endian.h
index de172fe..799a6f2 100644
--- a/libc/include/sys/endian.h
+++ b/libc/include/sys/endian.h
@@ -49,10 +49,10 @@
/* glibc compatibility. */
__BEGIN_DECLS
-uint32_t htonl(uint32_t) __attribute_const__ __INTRODUCED_IN(21);
-uint16_t htons(uint16_t) __attribute_const__ __INTRODUCED_IN(21);
-uint32_t ntohl(uint32_t) __attribute_const__ __INTRODUCED_IN(21);
-uint16_t ntohs(uint16_t) __attribute_const__ __INTRODUCED_IN(21);
+uint32_t htonl(uint32_t __x) __attribute_const__ __INTRODUCED_IN(21);
+uint16_t htons(uint16_t __x) __attribute_const__ __INTRODUCED_IN(21);
+uint32_t ntohl(uint32_t __x) __attribute_const__ __INTRODUCED_IN(21);
+uint16_t ntohs(uint16_t __x) __attribute_const__ __INTRODUCED_IN(21);
__END_DECLS
#define htonl(x) __swap32(x)
@@ -103,4 +103,4 @@
#define le64toh(x) htole64(x)
#endif /* __USE_BSD */
-#endif /* _SYS_ENDIAN_H_ */
+#endif
diff --git a/libc/include/sys/epoll.h b/libc/include/sys/epoll.h
index 5e92fdc..6ecd93f 100644
--- a/libc/include/sys/epoll.h
+++ b/libc/include/sys/epoll.h
@@ -34,29 +34,9 @@
#include <signal.h> /* For sigset_t. */
#include <linux/eventpoll.h>
-/* TODO: https://lkml.org/lkml/2017/2/23/416 has a better fix. */
-#undef EPOLLWAKEUP
-#undef EPOLLONESHOT
-#undef EPOLLET
__BEGIN_DECLS
-/* TODO: remove once https://lkml.org/lkml/2017/2/23/417 is upstream. */
-#define EPOLLIN 0x00000001
-#define EPOLLPRI 0x00000002
-#define EPOLLOUT 0x00000004
-#define EPOLLERR 0x00000008
-#define EPOLLHUP 0x00000010
-#define EPOLLRDNORM 0x00000040
-#define EPOLLRDBAND 0x00000080
-#define EPOLLWRNORM 0x00000100
-#define EPOLLWRBAND 0x00000200
-#define EPOLLMSG 0x00000400
-#define EPOLLRDHUP 0x00002000
-#define EPOLLWAKEUP 0x20000000
-#define EPOLLONESHOT 0x40000000
-#define EPOLLET 0x80000000
-
typedef union epoll_data {
void* ptr;
int fd;
@@ -73,8 +53,8 @@
#endif
;
-int epoll_create(int);
-int epoll_create1(int) __INTRODUCED_IN(21);
+int epoll_create(int __size);
+int epoll_create1(int __flags) __INTRODUCED_IN(21);
/*
* Some third-party code uses the existence of EPOLL_CLOEXEC to detect the
@@ -91,10 +71,10 @@
#undef EPOLL_CLOEXEC
#endif
-int epoll_ctl(int, int, int, struct epoll_event*);
-int epoll_wait(int, struct epoll_event*, int, int);
-int epoll_pwait(int, struct epoll_event*, int, int, const sigset_t*) __INTRODUCED_IN(21);
+int epoll_ctl(int __epoll_fd, int __op, int __fd, struct epoll_event* __event);
+int epoll_wait(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms);
+int epoll_pwait(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms, const sigset_t* __mask) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* _SYS_EPOLL_H_ */
+#endif
diff --git a/libc/include/sys/eventfd.h b/libc/include/sys/eventfd.h
index 6b9749a..3cfb5e7 100644
--- a/libc/include/sys/eventfd.h
+++ b/libc/include/sys/eventfd.h
@@ -37,14 +37,13 @@
#define EFD_CLOEXEC O_CLOEXEC
#define EFD_NONBLOCK O_NONBLOCK
-/* type of event counter */
typedef uint64_t eventfd_t;
-int eventfd(unsigned int initial_value, int flags);
+int eventfd(unsigned int __initial_value, int __flags);
-int eventfd_read(int fd, eventfd_t* value);
-int eventfd_write(int fd, eventfd_t value);
+int eventfd_read(int __fd, eventfd_t* __value);
+int eventfd_write(int __fd, eventfd_t __value);
__END_DECLS
-#endif /* _SYS_EVENTFD_H */
+#endif
diff --git a/libc/include/sys/file.h b/libc/include/sys/file.h
index f414d34..a420021 100644
--- a/libc/include/sys/file.h
+++ b/libc/include/sys/file.h
@@ -36,8 +36,8 @@
__BEGIN_DECLS
-int flock(int, int);
+int flock(int __fd, int __op);
__END_DECLS
-#endif /* _SYS_FILE_H_ */
+#endif
diff --git a/libc/include/sys/fsuid.h b/libc/include/sys/fsuid.h
index e4d9ebc..bb7a58d 100644
--- a/libc/include/sys/fsuid.h
+++ b/libc/include/sys/fsuid.h
@@ -34,9 +34,9 @@
__BEGIN_DECLS
-int setfsuid(uid_t) __INTRODUCED_IN(21);
-int setfsgid(gid_t) __INTRODUCED_IN(21);
+int setfsuid(uid_t __uid) __INTRODUCED_IN(21);
+int setfsgid(gid_t __gid) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* _SYS_FSUID_H_ */
+#endif
diff --git a/libc/include/sys/inotify.h b/libc/include/sys/inotify.h
index 98f7198..32e16d9 100644
--- a/libc/include/sys/inotify.h
+++ b/libc/include/sys/inotify.h
@@ -54,10 +54,10 @@
#endif
int inotify_init(void);
-int inotify_init1(int) __INTRODUCED_IN(21);
-int inotify_add_watch(int, const char*, uint32_t);
-int inotify_rm_watch(int, uint32_t);
+int inotify_init1(int __flags) __INTRODUCED_IN(21);
+int inotify_add_watch(int __fd, const char* __path, uint32_t __mask);
+int inotify_rm_watch(int __fd, uint32_t __watch_descriptor);
__END_DECLS
-#endif /* _SYS_INOTIFY_H_ */
+#endif
diff --git a/libc/include/sys/ioctl.h b/libc/include/sys/ioctl.h
index efbcb0c..76dc1ff 100644
--- a/libc/include/sys/ioctl.h
+++ b/libc/include/sys/ioctl.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _SYS_IOCTL_H_
#define _SYS_IOCTL_H_
@@ -41,4 +42,4 @@
#include <bits/ioctl.h>
-#endif /* _SYS_IOCTL_H_ */
+#endif
diff --git a/libc/include/sys/ipc.h b/libc/include/sys/ipc.h
index 3d6c45f..dee7c8a 100644
--- a/libc/include/sys/ipc.h
+++ b/libc/include/sys/ipc.h
@@ -42,8 +42,8 @@
__BEGIN_DECLS
-key_t ftok(const char* path, int id);
+key_t ftok(const char* __path, int __id);
__END_DECLS
-#endif /* _SYS_IPC_H */
+#endif
diff --git a/libc/include/sys/klog.h b/libc/include/sys/klog.h
index 47eb3a4..ed746fc 100644
--- a/libc/include/sys/klog.h
+++ b/libc/include/sys/klog.h
@@ -46,8 +46,8 @@
#define KLOG_SIZE_UNREAD 9
#define KLOG_SIZE_BUFFER 10
-int klogctl(int, char *, int);
+int klogctl(int __type, char* __buf, int __buf_size);
__END_DECLS
-#endif /* _SYS_KLOG_H_ */
+#endif
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 1440dc6..1e752c4 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _SYS_MMAN_H_
#define _SYS_MMAN_H_
@@ -44,27 +45,27 @@
#define MREMAP_FIXED 2
#if defined(__USE_FILE_OFFSET64)
-void* mmap(void*, size_t, int, int, int, off_t) __RENAME(mmap64) __INTRODUCED_IN(21);
+void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset) __RENAME(mmap64) __INTRODUCED_IN(21);
#else
-void* mmap(void*, size_t, int, int, int, off_t);
+void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset);
#endif
-void* mmap64(void*, size_t, int, int, int, off64_t) __INTRODUCED_IN(21);
+void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset) __INTRODUCED_IN(21);
-int munmap(void*, size_t);
-int msync(void*, size_t, int);
-int mprotect(void*, size_t, int);
-void* mremap(void*, size_t, size_t, int, ...);
+int munmap(void* __addr, size_t __size);
+int msync(void* __addr, size_t __size, int __flags);
+int mprotect(void* __addr, size_t __size, int __prot);
+void* mremap(void* __old_addr, size_t __old_size, size_t __new_size, int __flags, ...);
-int mlockall(int) __INTRODUCED_IN(17);
+int mlockall(int __flags) __INTRODUCED_IN(17);
int munlockall(void) __INTRODUCED_IN(17);
-int mlock(const void*, size_t);
-int munlock(const void*, size_t);
+int mlock(const void* __addr, size_t __size);
+int munlock(const void* __addr, size_t __size);
-int mincore(void*, size_t, unsigned char*);
+int mincore(void* __addr, size_t __size, unsigned char* __vector);
-int madvise(void*, size_t, int);
+int madvise(void* __addr, size_t __size, int __advice);
#if __ANDROID_API__ >= __ANDROID_API_M__
/*
@@ -81,8 +82,8 @@
#define POSIX_MADV_WILLNEED MADV_WILLNEED
#define POSIX_MADV_DONTNEED MADV_DONTNEED
#endif
-int posix_madvise(void*, size_t, int) __INTRODUCED_IN(23);
+int posix_madvise(void* __addr, size_t __size, int __advice) __INTRODUCED_IN(23);
__END_DECLS
-#endif /* _SYS_MMAN_H_ */
+#endif
diff --git a/libc/include/sys/mount.h b/libc/include/sys/mount.h
index 26c0e0f..c0c084b 100644
--- a/libc/include/sys/mount.h
+++ b/libc/include/sys/mount.h
@@ -41,10 +41,10 @@
#define MNT_EXPIRE 4
#define UMOUNT_NOFOLLOW 8
-int mount(const char*, const char*, const char*, unsigned long, const void*);
-int umount(const char*);
-int umount2(const char*, int);
+int mount(const char* __source, const char* __target, const char* __fs_type, unsigned long __flags, const void* __data);
+int umount(const char* __target);
+int umount2(const char* __target, int __flags);
__END_DECLS
-#endif /* _SYS_MOUNT_H */
+#endif
diff --git a/libc/include/sys/msg.h b/libc/include/sys/msg.h
index ced5a3e..0273499 100644
--- a/libc/include/sys/msg.h
+++ b/libc/include/sys/msg.h
@@ -41,11 +41,11 @@
typedef __kernel_ulong_t msgqnum_t;
typedef __kernel_ulong_t msglen_t;
-int msgctl(int, int, struct msqid_ds*) __INTRODUCED_IN(26);
-int msgget(key_t, int) __INTRODUCED_IN(26);
-ssize_t msgrcv(int, void*, size_t, long, int) __INTRODUCED_IN(26);
-int msgsnd(int, const void*, size_t, int) __INTRODUCED_IN(26);
+int msgctl(int __msg_id, int __cmd, struct msqid_ds* __buf) __INTRODUCED_IN(26);
+int msgget(key_t __key, int __flags) __INTRODUCED_IN(26);
+ssize_t msgrcv(int __msg_id, void* __msgbuf_ptr, size_t __size, long __type, int __flags) __INTRODUCED_IN(26);
+int msgsnd(int __msg_id, const void* __msgbuf_ptr, size_t __size, int __flags) __INTRODUCED_IN(26);
__END_DECLS
-#endif /* _SYS_MSG_H_ */
+#endif
diff --git a/libc/include/sys/param.h b/libc/include/sys/param.h
index d3686e0..ec50da2 100644
--- a/libc/include/sys/param.h
+++ b/libc/include/sys/param.h
@@ -49,4 +49,4 @@
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
-#endif /* _SYS_PARAM_H_ */
+#endif
diff --git a/libc/include/sys/personality.h b/libc/include/sys/personality.h
index 6f3a3c9..51b5cd7 100644
--- a/libc/include/sys/personality.h
+++ b/libc/include/sys/personality.h
@@ -34,8 +34,8 @@
__BEGIN_DECLS
-int personality(unsigned int persona) __INTRODUCED_IN(15);
+int personality(unsigned int __persona) __INTRODUCED_IN(15);
__END_DECLS
-#endif /* _SYS_PERSONALITY_H_ */
+#endif
diff --git a/libc/include/sys/prctl.h b/libc/include/sys/prctl.h
index 742ed57..64f5954 100644
--- a/libc/include/sys/prctl.h
+++ b/libc/include/sys/prctl.h
@@ -35,8 +35,8 @@
__BEGIN_DECLS
-int prctl(int option, ...);
+int prctl(int __option, ...);
__END_DECLS
-#endif /* _SYS_PRCTL_H */
+#endif
diff --git a/libc/include/sys/procfs.h b/libc/include/sys/procfs.h
index eff39e2..75a1e98 100644
--- a/libc/include/sys/procfs.h
+++ b/libc/include/sys/procfs.h
@@ -59,4 +59,4 @@
__END_DECLS
-#endif /* _SYS_PROCFS_H_ */
+#endif
diff --git a/libc/include/sys/ptrace.h b/libc/include/sys/ptrace.h
index 4b881e7..022fc3a 100644
--- a/libc/include/sys/ptrace.h
+++ b/libc/include/sys/ptrace.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _SYS_PTRACE_H_
#define _SYS_PTRACE_H_
@@ -58,8 +59,8 @@
#define PT_GETSIGINFO PTRACE_GETSIGINFO
#define PT_SETSIGINFO PTRACE_SETSIGINFO
-long ptrace(int, ...);
+long ptrace(int __request, ...);
__END_DECLS
-#endif /* _SYS_PTRACE_H_ */
+#endif
diff --git a/libc/include/sys/quota.h b/libc/include/sys/quota.h
index 51f7675..157c2d9 100644
--- a/libc/include/sys/quota.h
+++ b/libc/include/sys/quota.h
@@ -40,7 +40,7 @@
__BEGIN_DECLS
-int quotactl(int, const char*, int, char*) __INTRODUCED_IN(26);
+int quotactl(int __cmd, const char* __special, int __id, char* __addr) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/libc/include/sys/reboot.h b/libc/include/sys/reboot.h
index df4739e..c0c4860 100644
--- a/libc/include/sys/reboot.h
+++ b/libc/include/sys/reboot.h
@@ -42,8 +42,8 @@
#define RB_DISABLE_CAD LINUX_REBOOT_CMD_CAD_OFF
#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF
-int reboot(int reboot_type);
+int reboot(int __cmd);
__END_DECLS
-#endif /* _SYS_REBOOT_H_ */
+#endif
diff --git a/libc/include/sys/reg.h b/libc/include/sys/reg.h
index 1066b6d..6c496ba 100644
--- a/libc/include/sys/reg.h
+++ b/libc/include/sys/reg.h
@@ -83,4 +83,4 @@
#endif
-#endif /* _SYS_REG_H_ */
+#endif
diff --git a/libc/include/sys/resource.h b/libc/include/sys/resource.h
index 7c43ca3..9181125 100644
--- a/libc/include/sys/resource.h
+++ b/libc/include/sys/resource.h
@@ -42,21 +42,20 @@
typedef unsigned long rlim_t;
-int getrlimit(int, struct rlimit*);
-int setrlimit(int, const struct rlimit*);
+int getrlimit(int __resource, struct rlimit* __limit);
+int setrlimit(int __resource, const struct rlimit* __limit);
-int getrlimit64(int, struct rlimit64*) __INTRODUCED_IN(21);
-int setrlimit64(int, const struct rlimit64*) __INTRODUCED_IN(21);
+int getrlimit64(int __resource, struct rlimit64* __limit) __INTRODUCED_IN(21);
+int setrlimit64(int __resource, const struct rlimit64* __limit) __INTRODUCED_IN(21);
-int getpriority(int, id_t);
-int setpriority(int, id_t, int);
+int getpriority(int __which, id_t __who);
+int setpriority(int __which, id_t __who, int __priority);
-int getrusage(int, struct rusage*);
+int getrusage(int __who, struct rusage* __usage);
-int prlimit(pid_t, int, const struct rlimit*, struct rlimit*) __INTRODUCED_IN_32(24)
- __INTRODUCED_IN_64(21);
-int prlimit64(pid_t, int, const struct rlimit64*, struct rlimit64*) __INTRODUCED_IN(21);
+int prlimit(pid_t __pid, int __resource, const struct rlimit* __new_limit, struct rlimit* __old_limit) __INTRODUCED_IN_32(24) __INTRODUCED_IN_64(21);
+int prlimit64(pid_t __pid, int __resource, const struct rlimit64* __new_limit, struct rlimit64* __old_limit) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* _SYS_RESOURCE_H_ */
+#endif
diff --git a/libc/include/sys/select.h b/libc/include/sys/select.h
index 40bd32e..e919188 100644
--- a/libc/include/sys/select.h
+++ b/libc/include/sys/select.h
@@ -72,9 +72,9 @@
#define FD_ISSET(fd, set) ((__FDS_BITS(set)[__FDELT(fd)] & __FDMASK(fd)) != 0)
#endif /* defined(__BIONIC_FORTIFY) && __ANDROID_API >= 21 */
-int select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
-int pselect(int, fd_set*, fd_set*, fd_set*, const struct timespec*, const sigset_t*);
+int select(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, struct timeval* __timeout);
+int pselect(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset_t* __mask);
__END_DECLS
-#endif /* _SYS_SELECT_H_ */
+#endif
diff --git a/libc/include/sys/sem.h b/libc/include/sys/sem.h
index be0e22d..cd62242 100644
--- a/libc/include/sys/sem.h
+++ b/libc/include/sys/sem.h
@@ -51,12 +51,12 @@
void* __pad;
};
-int semctl(int, int, int, ...) __INTRODUCED_IN(26);
-int semget(key_t, int, int) __INTRODUCED_IN(26);
-int semop(int, struct sembuf*, size_t) __INTRODUCED_IN(26);
+int semctl(int __sem_id, int __sem_num, int __cmd, ...) __INTRODUCED_IN(26);
+int semget(key_t __key, int __sem_count, int __flags) __INTRODUCED_IN(26);
+int semop(int __sem_id, struct sembuf* __ops, size_t __op_count) __INTRODUCED_IN(26);
#if defined(__USE_GNU)
-int semtimedop(int, struct sembuf*, size_t, const struct timespec*) __INTRODUCED_IN(26);
+int semtimedop(int __sem_id, struct sembuf* __ops, size_t __op_count, const struct timespec* __timeout) __INTRODUCED_IN(26);
#endif
__END_DECLS
diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h
index 43b334c..ecdb76c 100644
--- a/libc/include/sys/sendfile.h
+++ b/libc/include/sys/sendfile.h
@@ -35,12 +35,12 @@
__BEGIN_DECLS
#if defined(__USE_FILE_OFFSET64)
-ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) __RENAME(sendfile64) __INTRODUCED_IN(21);
+ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count) __RENAME(sendfile64) __INTRODUCED_IN(21);
#else
-ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);
+ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count);
#endif
-ssize_t sendfile64(int out_fd, int in_fd, off64_t* offset, size_t count) __INTRODUCED_IN(21);
+ssize_t sendfile64(int __out_fd, int __in_fd, off64_t* __offset, size_t __count) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* _SYS_SENDFILE_H_ */
+#endif
diff --git a/libc/include/sys/shm.h b/libc/include/sys/shm.h
index ccd3b36..4723eba 100644
--- a/libc/include/sys/shm.h
+++ b/libc/include/sys/shm.h
@@ -42,10 +42,10 @@
typedef unsigned long shmatt_t;
-void* shmat(int, const void*, int) __INTRODUCED_IN(26);
-int shmctl(int, int, struct shmid_ds*) __INTRODUCED_IN(26);
-int shmdt(const void*) __INTRODUCED_IN(26);
-int shmget(key_t, size_t, int) __INTRODUCED_IN(26);
+void* shmat(int __shm_id, const void* __addr, int __flags) __INTRODUCED_IN(26);
+int shmctl(int __shm_id, int __cmd, struct shmid_ds* __buf) __INTRODUCED_IN(26);
+int shmdt(const void* __addr) __INTRODUCED_IN(26);
+int shmget(key_t __key, size_t __size, int __flags) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/libc/include/sys/signalfd.h b/libc/include/sys/signalfd.h
index 79f9490..315622c 100644
--- a/libc/include/sys/signalfd.h
+++ b/libc/include/sys/signalfd.h
@@ -36,8 +36,8 @@
__BEGIN_DECLS
-int signalfd(int fd, const sigset_t* _Nonnull mask, int flags) __INTRODUCED_IN(18);
+int signalfd(int __fd, const sigset_t* __mask, int __flags) __INTRODUCED_IN(18);
__END_DECLS
-#endif /* _SYS_SIGNALFD_H */
+#endif
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 2dc54aa..ed851a2 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -115,7 +115,7 @@
#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && (cmsg)->cmsg_len <= (unsigned long) ((mhdr)->msg_controllen - ((char*)(cmsg) - (char*)(mhdr)->msg_control)))
#if __ANDROID_API__ >= __ANDROID_API_L__
-struct cmsghdr* __cmsg_nxthdr(struct msghdr*, struct cmsghdr*) __INTRODUCED_IN(21);
+struct cmsghdr* __cmsg_nxthdr(struct msghdr* __msg, struct cmsghdr* __cmsg) __INTRODUCED_IN(21);
#else
/* TODO(danalbert): Move this into libandroid_support. */
static inline struct cmsghdr* __cmsg_nxthdr(struct msghdr* msg, struct cmsghdr* cmsg) {
@@ -299,169 +299,37 @@
# define __socketcall extern
#endif
-__socketcall int accept(int, struct sockaddr*, socklen_t*);
-__socketcall int accept4(int, struct sockaddr*, socklen_t*, int) __INTRODUCED_IN(21);
-__socketcall int bind(int, const struct sockaddr*, socklen_t);
-__socketcall int connect(int, const struct sockaddr*, socklen_t);
-__socketcall int getpeername(int, struct sockaddr*, socklen_t*);
-__socketcall int getsockname(int, struct sockaddr*, socklen_t*);
-__socketcall int getsockopt(int, int, int, void*, socklen_t*);
-__socketcall int listen(int, int);
-__socketcall int recvmmsg(int, struct mmsghdr*, unsigned int, int, const struct timespec*)
+__socketcall int accept(int __fd, struct sockaddr* __addr, socklen_t* __addr_length);
+__socketcall int accept4(int __fd, struct sockaddr* __addr, socklen_t* __addr_length, int __flags) __INTRODUCED_IN(21);
+__socketcall int bind(int __fd, const struct sockaddr* __addr, socklen_t __addr_length);
+__socketcall int connect(int __fd, const struct sockaddr* __addr, socklen_t __addr_length);
+__socketcall int getpeername(int __fd, struct sockaddr* __addr, socklen_t* __addr_length);
+__socketcall int getsockname(int __fd, struct sockaddr* __addr, socklen_t* __addr_length);
+__socketcall int getsockopt(int __fd, int __level, int __option, void* __value, socklen_t* __value_length);
+__socketcall int listen(int __fd, int __backlog);
+__socketcall int recvmmsg(int __fd, struct mmsghdr* __msgs, unsigned int __msg_count, int __flags, const struct timespec* __timeout)
__INTRODUCED_IN(21);
-__socketcall ssize_t recvmsg(int, struct msghdr*, int);
-__socketcall int sendmmsg(int, const struct mmsghdr*, unsigned int, int) __INTRODUCED_IN(21);
-__socketcall ssize_t sendmsg(int, const struct msghdr*, int);
-__socketcall int setsockopt(int, int, int, const void*, socklen_t);
-__socketcall int shutdown(int, int);
-__socketcall int socket(int, int, int);
-__socketcall int socketpair(int, int, int, int*);
+__socketcall ssize_t recvmsg(int __fd, struct msghdr* __msg, int __flags);
+__socketcall int sendmmsg(int __fd, const struct mmsghdr* __msgs, unsigned int __msg_count, int __flags) __INTRODUCED_IN(21);
+__socketcall ssize_t sendmsg(int __fd, const struct msghdr* __msg, int __flags);
+__socketcall int setsockopt(int __fd, int __level, int __option, const void* __value, socklen_t __value_length);
+__socketcall int shutdown(int __fd, int __how);
+__socketcall int socket(int __af, int __type, int __protocol);
+__socketcall int socketpair(int __af, int __type, int __protocol, int __fds[2]);
-ssize_t recv(int, void*, size_t, int) __overloadable __RENAME_CLANG(recv);
-ssize_t send(int, const void*, size_t, int) __overloadable __RENAME_CLANG(send);
+ssize_t recv(int __fd, void* __buf, size_t __n, int __flags) __overloadable __RENAME_CLANG(recv);
+ssize_t send(int __fd, const void* __buf, size_t __n, int __flags) __overloadable __RENAME_CLANG(send);
-__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t)
+__socketcall ssize_t sendto(int __fd, const void* __buf, size_t __n, int __flags, const struct sockaddr* __dst_addr, socklen_t __dst_addr_length)
__overloadable __RENAME_CLANG(sendto);
-__socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*,
- socklen_t*) __overloadable __RENAME_CLANG(recvfrom);
+__socketcall ssize_t recvfrom(int __fd, void* __buf, size_t __n, int __flags, struct sockaddr* __src_addr, socklen_t* __src_addr_length) __overloadable __RENAME_CLANG(recvfrom);
-extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
- socklen_t) __INTRODUCED_IN(26);
-ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
- socklen_t*) __INTRODUCED_IN(21);
-
-#if defined(__BIONIC_FORTIFY)
-
-#define __recvfrom_bad_size "recvfrom called with size bigger than buffer"
-#define __sendto_bad_size "sendto called with size bigger than buffer"
-#if defined(__clang__)
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len,
- int flags, struct sockaddr* src_addr, socklen_t* addr_len)
- __overloadable
- __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(buf) < len, "selected when the buffer is too small")
- __errorattr(__recvfrom_bad_size);
-
-__BIONIC_FORTIFY_INLINE
-ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len,
- int flags, struct sockaddr* src_addr, socklen_t* addr_len)
- __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr,
- addr_len);
- }
-
- return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t sendto(int fd, const void* buf, size_t len, int flags,
- const struct sockaddr* dest_addr, socklen_t addr_len)
- __overloadable
- __enable_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos0(buf) < len, "selected when the buffer is too small")
- __errorattr(__sendto_bad_size);
-
-__BIONIC_FORTIFY_INLINE
-ssize_t sendto(int fd, const void* const buf __pass_object_size0, size_t len,
- int flags, const struct sockaddr* dest_addr, socklen_t addr_len)
- __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(sendto)(fd, buf, len, flags, dest_addr,
- addr_len);
- }
-
- return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t send(int socket, const void* buf, size_t len, int flags)
- __overloadable
- __enable_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos0(buf) < len, "selected when the buffer is too small")
- __errorattr("send called with size bigger than buffer");
-#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
-
-#else /* defined(__clang__) */
-ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
-__errordecl(__recvfrom_error, __recvfrom_bad_size);
-
-extern ssize_t __sendto_real(int, const void*, size_t, int, const struct sockaddr*, socklen_t)
- __RENAME(sendto);
-__errordecl(__sendto_error, __sendto_bad_size);
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
- struct sockaddr* src_addr, socklen_t* addr_len) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
- }
-
- if (__builtin_constant_p(len) && (len <= bos)) {
- return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
- }
-
- if (__builtin_constant_p(len) && (len > bos)) {
- __recvfrom_error();
- }
-
- return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
-__BIONIC_FORTIFY_INLINE
-ssize_t sendto(int fd, const void* buf, size_t len, int flags,
- const struct sockaddr* dest_addr, socklen_t addr_len) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
- }
-
- if (__builtin_constant_p(len) && (len <= bos)) {
- return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
- }
-
- if (__builtin_constant_p(len) && (len > bos)) {
- __sendto_error();
- }
-
- return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
-
-#endif /* defined(__clang__) */
-#undef __recvfrom_bad_size
-#undef __sendto_bad_size
-
-__BIONIC_FORTIFY_INLINE
-ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len,
- int flags) __overloadable {
- return recvfrom(socket, buf, len, flags, NULL, 0);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t send(int socket, const void* const buf __pass_object_size0, size_t len, int flags)
- __overloadable {
- return sendto(socket, buf, len, flags, NULL, 0);
-}
-
-#endif /* __BIONIC_FORTIFY */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/socket.h>
+#endif
#undef __socketcall
__END_DECLS
-#endif /* _SYS_SOCKET_H */
+#endif
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 47ff5c4..14b5224 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -151,88 +151,46 @@
#define S_TYPEISSHM(__sb) 0
#define S_TYPEISTMO(__sb) 0
-int chmod(const char*, mode_t);
-int fchmod(int, mode_t);
-int mkdir(const char*, mode_t);
+int chmod(const char* __path, mode_t __mode);
+int fchmod(int __fd, mode_t __mode);
+int mkdir(const char* __path, mode_t __mode);
-int fstat(int, struct stat*);
-int fstat64(int, struct stat64*) __INTRODUCED_IN(21);
-int fstatat(int, const char*, struct stat*, int);
-int fstatat64(int, const char*, struct stat64*, int) __INTRODUCED_IN(21);
-int lstat(const char*, struct stat*);
-int lstat64(const char*, struct stat64*) __INTRODUCED_IN(21);
-int stat(const char*, struct stat*);
-int stat64(const char*, struct stat64*) __INTRODUCED_IN(21);
+int fstat(int __fd, struct stat* __buf);
+int fstat64(int __fd, struct stat64* __buf) __INTRODUCED_IN(21);
+int fstatat(int __dir_fd, const char* __path, struct stat* __buf, int __flags);
+int fstatat64(int __dir_fd, const char* __path, struct stat64* __buf, int __flags) __INTRODUCED_IN(21);
+int lstat(const char* __path, struct stat* __buf);
+int lstat64(const char* __path, struct stat64* __buf) __INTRODUCED_IN(21);
+int stat(const char* __path, struct stat* __buf);
+int stat64(const char* __path, struct stat64* __buf) __INTRODUCED_IN(21);
-int mknod(const char*, mode_t, dev_t);
-mode_t umask(mode_t) __overloadable __RENAME_CLANG(umask);
+int mknod(const char* __path, mode_t __mode, dev_t __dev);
+mode_t umask(mode_t __mask) __overloadable __RENAME_CLANG(umask);
-mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
-
-#if defined(__BIONIC_FORTIFY)
-#define __umask_invalid_mode_str "umask called with invalid mode"
-
-#if defined(__clang__)
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
-/*
- * Abuse enable_if to make these be seen as overloads of umask, rather than
- * definitions.
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-mode_t umask(mode_t mode) __overloadable
- __enable_if(1, "")
- __enable_if(mode & ~0777, __umask_invalid_mode_str)
- __errorattr(__umask_invalid_mode_str);
-
-__BIONIC_FORTIFY_INLINE
-mode_t umask(mode_t mode) __enable_if(1, "") __overloadable {
- return __umask_chk(mode);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-
-#else /* defined(__clang__) */
-__errordecl(__umask_invalid_mode, __umask_invalid_mode_str);
-extern mode_t __umask_real(mode_t) __RENAME(umask);
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
-__BIONIC_FORTIFY_INLINE
-mode_t umask(mode_t mode) {
- if (__builtin_constant_p(mode)) {
- if ((mode & 0777) != mode) {
- __umask_invalid_mode();
- }
- return __umask_real(mode);
- }
- return __umask_chk(mode);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-
-#endif /* defined(__clang__) */
-#undef __umask_invalid_mode_str
-
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stat.h>
+#endif
#if __ANDROID_API__ >= __ANDROID_API_L__
-int mkfifo(const char*, mode_t) __INTRODUCED_IN(21);
+int mkfifo(const char* __path, mode_t __mode) __INTRODUCED_IN(21);
#else
// Implemented as a static inline before 21.
#endif
-int mkfifoat(int, const char*, mode_t) __INTRODUCED_IN(23);
+int mkfifoat(int __dir_fd, const char* __path, mode_t __mode) __INTRODUCED_IN(23);
-int fchmodat(int, const char*, mode_t, int);
-int mkdirat(int, const char*, mode_t);
-int mknodat(int, const char*, mode_t, dev_t) __INTRODUCED_IN(21);
+int fchmodat(int __dir_fd, const char* __path, mode_t __mode, int __flags);
+int mkdirat(int __dir_fd, const char* __path, mode_t __mode);
+int mknodat(int __dir_fd, const char* __path, mode_t __mode, dev_t __dev) __INTRODUCED_IN(21);
#define UTIME_NOW ((1L << 30) - 1L)
#define UTIME_OMIT ((1L << 30) - 2L)
-int utimensat(int fd, const char* path, const struct timespec times[2], int flags)
+int utimensat(int __dir_fd, const char* __path, const struct timespec __times[2], int __flags)
__INTRODUCED_IN(12);
-int futimens(int fd, const struct timespec times[2]) __INTRODUCED_IN(19);
+int futimens(int __dir_fd, const struct timespec __times[2]) __INTRODUCED_IN(19);
__END_DECLS
#include <android/legacy_sys_stat_inlines.h>
-#endif /* _SYS_STAT_H_ */
+#endif
diff --git a/libc/include/sys/statvfs.h b/libc/include/sys/statvfs.h
index af1b9c0..e60cadc 100644
--- a/libc/include/sys/statvfs.h
+++ b/libc/include/sys/statvfs.h
@@ -59,13 +59,11 @@
#define ST_NODIRATIME 0x0800
#define ST_RELATIME 0x1000
-int statvfs(const char* __restrict _Nonnull, struct statvfs* __restrict _Nonnull)
- __INTRODUCED_IN(19);
-int statvfs64(const char* __restrict _Nonnull, struct statvfs64* __restrict _Nonnull)
- __INTRODUCED_IN(21);
-int fstatvfs(int, struct statvfs* _Nonnull) __INTRODUCED_IN(19);
-int fstatvfs64(int, struct statvfs64* _Nonnull) __INTRODUCED_IN(21);
+int statvfs(const char* __path, struct statvfs* __buf) __INTRODUCED_IN(19);
+int statvfs64(const char* __path, struct statvfs64* __buf) __INTRODUCED_IN(21);
+int fstatvfs(int __fd, struct statvfs* __buf) __INTRODUCED_IN(19);
+int fstatvfs64(int __fd, struct statvfs64* __buf) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* _SYS_STATVFS_H_ */
+#endif
diff --git a/libc/include/sys/swap.h b/libc/include/sys/swap.h
index 3444736..8a30cce 100644
--- a/libc/include/sys/swap.h
+++ b/libc/include/sys/swap.h
@@ -38,9 +38,9 @@
#define SWAP_FLAG_PRIO_MASK 0x7fff
#define SWAP_FLAG_PRIO_SHIFT 0
-int swapon(const char* _Nonnull, int) __INTRODUCED_IN(19);
-int swapoff(const char* _Nonnull) __INTRODUCED_IN(19);
+int swapon(const char* __path, int __flags) __INTRODUCED_IN(19);
+int swapoff(const char* __path) __INTRODUCED_IN(19);
__END_DECLS
-#endif /* _SYS_SWAP_H_ */
+#endif
diff --git a/libc/include/sys/sysinfo.h b/libc/include/sys/sysinfo.h
index 9a10d64..6da02ee 100644
--- a/libc/include/sys/sysinfo.h
+++ b/libc/include/sys/sysinfo.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _SYS_SYSINFO_H_
#define _SYS_SYSINFO_H_
@@ -33,16 +34,12 @@
__BEGIN_DECLS
-int sysinfo(struct sysinfo* info);
-
+int sysinfo(struct sysinfo* __info);
int get_nprocs_conf(void) __INTRODUCED_IN(23);
-
int get_nprocs(void) __INTRODUCED_IN(23);
-
long get_phys_pages(void) __INTRODUCED_IN(23);
-
long get_avphys_pages(void) __INTRODUCED_IN(23);
__END_DECLS
-#endif /* _SYS_SYSINFO_H_ */
+#endif
diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h
index d075859..f469599 100644
--- a/libc/include/sys/system_properties.h
+++ b/libc/include/sys/system_properties.h
@@ -41,9 +41,9 @@
#define PROP_VALUE_MAX 92
/*
- * Sets system property `key` to `value`, creating the system property if it doesn't already exist.
+ * Sets system property `name` to `value`, creating the system property if it doesn't already exist.
*/
-int __system_property_set(const char* key, const char* value) __INTRODUCED_IN(12);
+int __system_property_set(const char* __name, const char* __value) __INTRODUCED_IN(12);
/*
* Returns a `prop_info` corresponding system property `name`, or nullptr if it doesn't exist.
@@ -51,14 +51,14 @@
*
* Property lookup is expensive, so it can be useful to cache the result of this function.
*/
-const prop_info* __system_property_find(const char* name);
+const prop_info* __system_property_find(const char* __name);
/*
* Calls `callback` with a consistent trio of name, value, and serial number for property `pi`.
*/
-void __system_property_read_callback(const prop_info *pi,
- void (*callback)(void* cookie, const char *name, const char *value, uint32_t serial),
- void* cookie) __INTRODUCED_IN(26);
+void __system_property_read_callback(const prop_info* __pi,
+ void (*__callback)(void* __cookie, const char* __name, const char* __value, uint32_t __serial),
+ void* __cookie) __INTRODUCED_IN(26);
/*
* Passes a `prop_info` for each system property to the provided
@@ -66,7 +66,7 @@
*
* This method is for inspecting and debugging the property system, and not generally useful.
*/
-int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie)
+int __system_property_foreach(void (*__callback)(const prop_info* __pi, void* __cookie), void* __cookie)
__INTRODUCED_IN(19);
/*
@@ -82,20 +82,17 @@
* timed out.
*/
struct timespec;
-bool __system_property_wait(const prop_info* pi,
- uint32_t old_serial,
- uint32_t* new_serial_ptr,
- const struct timespec* relative_timeout)
+bool __system_property_wait(const prop_info* __pi, uint32_t __old_serial, uint32_t* __new_serial_ptr, const struct timespec* __relative_timeout)
__INTRODUCED_IN(26);
/* Deprecated. In Android O and above, there's no limit on property name length. */
#define PROP_NAME_MAX 32
/* Deprecated. Use __system_property_read_callback instead. */
-int __system_property_read(const prop_info* pi, char* name, char* value);
+int __system_property_read(const prop_info* __pi, char* __name, char* __value);
/* Deprecated. Use __system_property_read_callback instead. */
-int __system_property_get(const char* name, char* value);
+int __system_property_get(const char* __name, char* __value);
/* Deprecated. Use __system_property_foreach instead. */
-const prop_info* __system_property_find_nth(unsigned n);
+const prop_info* __system_property_find_nth(unsigned __n);
__END_DECLS
diff --git a/libc/include/sys/time.h b/libc/include/sys/time.h
index 4d477e1..45190c3 100644
--- a/libc/include/sys/time.h
+++ b/libc/include/sys/time.h
@@ -38,21 +38,21 @@
__BEGIN_DECLS
-int gettimeofday(struct timeval*, struct timezone*);
-int settimeofday(const struct timeval*, const struct timezone*);
+int gettimeofday(struct timeval* __tv, struct timezone* __tz);
+int settimeofday(const struct timeval* __tv, const struct timezone* __tz);
-int getitimer(int, struct itimerval*);
-int setitimer(int, const struct itimerval*, struct itimerval*);
+int getitimer(int __which, struct itimerval* __current_value);
+int setitimer(int __which, const struct itimerval* __new_value, struct itimerval* __old_value);
-int utimes(const char*, const struct timeval*);
+int utimes(const char* __path, const struct timeval __times[2]);
#if defined(__USE_BSD)
-int futimes(int, const struct timeval[2]) __INTRODUCED_IN(26);
-int lutimes(const char*, const struct timeval[2]) __INTRODUCED_IN(26);
+int futimes(int __fd, const struct timeval __times[2]) __INTRODUCED_IN(26);
+int lutimes(const char* __path, const struct timeval __times[2]) __INTRODUCED_IN(26);
#endif
#if defined(__USE_GNU)
-int futimesat(int, const char*, const struct timeval[2]) __INTRODUCED_IN(26);
+int futimesat(int __dir_fd, const char* __path, const struct timeval __times[2]) __INTRODUCED_IN(26);
#endif
#define timerclear(a) \
@@ -97,4 +97,4 @@
__END_DECLS
-#endif /* _SYS_TIME_H_ */
+#endif
diff --git a/libc/include/sys/timerfd.h b/libc/include/sys/timerfd.h
index a500060..7bf675b 100644
--- a/libc/include/sys/timerfd.h
+++ b/libc/include/sys/timerfd.h
@@ -42,10 +42,10 @@
#define TFD_CLOEXEC O_CLOEXEC
#define TFD_NONBLOCK O_NONBLOCK
-int timerfd_create(clockid_t, int) __INTRODUCED_IN(19);
-int timerfd_settime(int, int, const struct itimerspec*, struct itimerspec*) __INTRODUCED_IN(19);
-int timerfd_gettime(int, struct itimerspec*) __INTRODUCED_IN(19);
+int timerfd_create(clockid_t __clock, int __flags) __INTRODUCED_IN(19);
+int timerfd_settime(int __fd, int __flags, const struct itimerspec* __new_value, struct itimerspec* __old_value) __INTRODUCED_IN(19);
+int timerfd_gettime(int __fd, struct itimerspec* __current_value) __INTRODUCED_IN(19);
__END_DECLS
-#endif /* _SYS_TIMERFD_H */
+#endif
diff --git a/libc/include/sys/times.h b/libc/include/sys/times.h
index f52db1f..3c8a4ef 100644
--- a/libc/include/sys/times.h
+++ b/libc/include/sys/times.h
@@ -35,8 +35,8 @@
__BEGIN_DECLS
-clock_t times(struct tms*);
+clock_t times(struct tms* __buf);
__END_DECLS
-#endif /* _SYS_TIMES_H_ */
+#endif
diff --git a/libc/include/sys/timex.h b/libc/include/sys/timex.h
index f704ce8..74c8611 100644
--- a/libc/include/sys/timex.h
+++ b/libc/include/sys/timex.h
@@ -35,9 +35,9 @@
__BEGIN_DECLS
-int adjtimex(struct timex*) __INTRODUCED_IN(24);
-int clock_adjtime(clockid_t, struct timex*) __INTRODUCED_IN(24);
+int adjtimex(struct timex* __buf) __INTRODUCED_IN(24);
+int clock_adjtime(clockid_t __clock, struct timex* __tx) __INTRODUCED_IN(24);
__END_DECLS
-#endif /* _SYS_TIMEX_H_ */
+#endif
diff --git a/libc/include/sys/uio.h b/libc/include/sys/uio.h
index 2611774..37961e3 100644
--- a/libc/include/sys/uio.h
+++ b/libc/include/sys/uio.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _SYS_UIO_H_
#define _SYS_UIO_H_
@@ -34,28 +35,21 @@
__BEGIN_DECLS
-ssize_t readv(int, const struct iovec*, int);
-ssize_t writev(int, const struct iovec*, int);
+ssize_t readv(int __fd, const struct iovec* __iov, int __count);
+ssize_t writev(int __fd, const struct iovec* __iov, int __count);
#if defined(__USE_GNU)
-#if defined(__USE_FILE_OFFSET64)
-ssize_t preadv(int, const struct iovec*, int, off_t) __RENAME(preadv64) __INTRODUCED_IN(24);
-ssize_t pwritev(int, const struct iovec*, int, off_t) __RENAME(pwritev64) __INTRODUCED_IN(24);
-#else
-ssize_t preadv(int, const struct iovec*, int, off_t) __INTRODUCED_IN(24);
-ssize_t pwritev(int, const struct iovec*, int, off_t) __INTRODUCED_IN(24);
-#endif
-ssize_t preadv64(int, const struct iovec*, int, off64_t) __INTRODUCED_IN(24);
-ssize_t pwritev64(int, const struct iovec*, int, off64_t) __INTRODUCED_IN(24);
+ssize_t preadv(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(preadv64) __INTRODUCED_IN(24);
+ssize_t pwritev(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(pwritev64) __INTRODUCED_IN(24);
+ssize_t preadv64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
+ssize_t pwritev64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
#endif
#if defined(__USE_GNU)
-ssize_t process_vm_readv(pid_t, const struct iovec*, unsigned long, const struct iovec*,
- unsigned long, unsigned long) __INTRODUCED_IN(23);
-ssize_t process_vm_writev(pid_t, const struct iovec*, unsigned long, const struct iovec*,
- unsigned long, unsigned long) __INTRODUCED_IN(23);
+ssize_t process_vm_readv(pid_t __pid, const struct iovec* __local_iov, unsigned long __local_iov_count, const struct iovec* __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
+ssize_t process_vm_writev(pid_t __pid, const struct iovec* __local_iov, unsigned long __local_iov_count, const struct iovec* __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
#endif
__END_DECLS
-#endif /* _SYS_UIO_H_ */
+#endif
diff --git a/libc/include/sys/utsname.h b/libc/include/sys/utsname.h
index b3856a7..2420fb4 100644
--- a/libc/include/sys/utsname.h
+++ b/libc/include/sys/utsname.h
@@ -36,16 +36,16 @@
#define SYS_NMLN 65
struct utsname {
- char sysname [SYS_NMLN];
- char nodename [SYS_NMLN];
- char release [SYS_NMLN];
- char version [SYS_NMLN];
- char machine [SYS_NMLN];
- char domainname[SYS_NMLN];
+ char sysname[SYS_NMLN];
+ char nodename[SYS_NMLN];
+ char release[SYS_NMLN];
+ char version[SYS_NMLN];
+ char machine[SYS_NMLN];
+ char domainname[SYS_NMLN];
};
-int uname(struct utsname*);
+int uname(struct utsname* __buf);
__END_DECLS
-#endif /* _SYS_UTSNAME_H_ */
+#endif
diff --git a/libc/include/sys/vfs.h b/libc/include/sys/vfs.h
index 1231eb1..9237ee6 100644
--- a/libc/include/sys/vfs.h
+++ b/libc/include/sys/vfs.h
@@ -137,11 +137,11 @@
#define XENIX_SUPER_MAGIC 0x012FF7B4
#define XFS_SUPER_MAGIC 0x58465342
-int statfs(const char* _Nonnull, struct statfs* _Nonnull);
-int statfs64(const char* _Nonnull, struct statfs64* _Nonnull) __INTRODUCED_IN(21);
-int fstatfs(int, struct statfs* _Nonnull);
-int fstatfs64(int, struct statfs64* _Nonnull) __INTRODUCED_IN(21);
+int statfs(const char* __path, struct statfs* __buf);
+int statfs64(const char* __path, struct statfs64* __buf) __INTRODUCED_IN(21);
+int fstatfs(int __fd, struct statfs* __buf);
+int fstatfs64(int __fd, struct statfs64* __buf) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* _SYS_VFS_H_ */
+#endif
diff --git a/libc/include/sys/wait.h b/libc/include/sys/wait.h
index 0247b2b..e259e31 100644
--- a/libc/include/sys/wait.h
+++ b/libc/include/sys/wait.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _SYS_WAIT_H_
#define _SYS_WAIT_H_
@@ -49,10 +50,10 @@
#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
-pid_t wait(int*);
-pid_t waitpid(pid_t, int*, int);
+pid_t wait(int* __status);
+pid_t waitpid(pid_t __pid, int* __status, int __options);
#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
-pid_t wait4(pid_t, int*, int, struct rusage*) __INTRODUCED_IN(18);
+pid_t wait4(pid_t __pid, int* __status, int __options, struct rusage* __rusage) __INTRODUCED_IN(18);
#else
// Implemented as a static inline before 18.
#endif
@@ -63,10 +64,10 @@
*/
typedef int idtype_t;
-int waitid(idtype_t which, id_t id, siginfo_t* info, int options);
+int waitid(idtype_t __type, id_t __id, siginfo_t* __info, int __options);
__END_DECLS
#include <android/legacy_sys_wait_inlines.h>
-#endif /* _SYS_WAIT_H_ */
+#endif
diff --git a/libc/include/sys/xattr.h b/libc/include/sys/xattr.h
index 37e352d..d15b3fc 100644
--- a/libc/include/sys/xattr.h
+++ b/libc/include/sys/xattr.h
@@ -35,25 +35,25 @@
__BEGIN_DECLS
-int fsetxattr(int fd, const char* name, const void* value, size_t size, int flags)
+int fsetxattr(int __fd, const char* __name, const void* __value, size_t __size, int __flags)
__INTRODUCED_IN(16);
-int setxattr(const char* path, const char* name, const void* value, size_t size, int flags)
+int setxattr(const char* __path, const char* __name, const void* __value, size_t __size, int __flags)
__INTRODUCED_IN(16);
-int lsetxattr(const char* path, const char* name, const void* value, size_t size, int flags)
+int lsetxattr(const char* __path, const char* __name, const void* __value, size_t __size, int __flags)
__INTRODUCED_IN(16);
-ssize_t fgetxattr(int fd, const char* name, void* value, size_t size) __INTRODUCED_IN(16);
-ssize_t getxattr(const char* path, const char* name, void* value, size_t size) __INTRODUCED_IN(16);
-ssize_t lgetxattr(const char* path, const char* name, void* value, size_t size) __INTRODUCED_IN(16);
+ssize_t fgetxattr(int __fd, const char* __name, void* __value, size_t __size) __INTRODUCED_IN(16);
+ssize_t getxattr(const char* __path, const char* __name, void* __value, size_t __size) __INTRODUCED_IN(16);
+ssize_t lgetxattr(const char* __path, const char* __name, void* __value, size_t __size) __INTRODUCED_IN(16);
-ssize_t listxattr(const char* path, char* list, size_t size) __INTRODUCED_IN(16);
-ssize_t llistxattr(const char* path, char* list, size_t size) __INTRODUCED_IN(16);
-ssize_t flistxattr(int fd, char* list, size_t size) __INTRODUCED_IN(16);
+ssize_t listxattr(const char* __path, char* __list, size_t __size) __INTRODUCED_IN(16);
+ssize_t llistxattr(const char* __path, char* __list, size_t __size) __INTRODUCED_IN(16);
+ssize_t flistxattr(int __fd, char* __list, size_t __size) __INTRODUCED_IN(16);
-int removexattr(const char* path, const char* name) __INTRODUCED_IN(16);
-int lremovexattr(const char* path, const char* name) __INTRODUCED_IN(16);
-int fremovexattr(int fd, const char* name) __INTRODUCED_IN(16);
+int removexattr(const char* __path, const char* __name) __INTRODUCED_IN(16);
+int lremovexattr(const char* __path, const char* __name) __INTRODUCED_IN(16);
+int fremovexattr(int __fd, const char* __name) __INTRODUCED_IN(16);
__END_DECLS
-#endif /* _SYS_XATTR_H_ */
+#endif
diff --git a/libc/include/syslog.h b/libc/include/syslog.h
index 4b7eecb..fff565e 100644
--- a/libc/include/syslog.h
+++ b/libc/include/syslog.h
@@ -50,28 +50,29 @@
#define LOG_MAKEPRI(fac, pri) ((fac) | (pri))
/* Facilities are currently ignored on Android. */
-#define LOG_KERN 0000
-#define LOG_USER 0010
-#define LOG_MAIL 0020
-#define LOG_DAEMON 0030
-#define LOG_AUTH 0040
-#define LOG_SYSLOG 0050
-#define LOG_LPR 0060
-#define LOG_NEWS 0070
-#define LOG_UUCP 0100
-#define LOG_CRON 0110
-#define LOG_AUTHPRIV 0120
-#define LOG_FTP 0130
-#define LOG_LOCAL0 0200
-#define LOG_LOCAL1 0210
-#define LOG_LOCAL2 0220
-#define LOG_LOCAL3 0230
-#define LOG_LOCAL4 0240
-#define LOG_LOCAL5 0250
-#define LOG_LOCAL6 0260
-#define LOG_LOCAL7 0270
+#define LOG_KERN (0<<3)
+#define LOG_USER (1<<3)
+#define LOG_MAIL (2<<3)
+#define LOG_DAEMON (3<<3)
+#define LOG_AUTH (4<<3)
+#define LOG_SYSLOG (5<<3)
+#define LOG_LPR (6<<3)
+#define LOG_NEWS (7<<3)
+#define LOG_UUCP (8<<3)
+#define LOG_CRON (9<<3)
+#define LOG_AUTHPRIV (10<<3)
+#define LOG_FTP (11<<3)
+#define LOG_LOCAL0 (16<<3)
+#define LOG_LOCAL1 (17<<3)
+#define LOG_LOCAL2 (18<<3)
+#define LOG_LOCAL3 (19<<3)
+#define LOG_LOCAL4 (20<<3)
+#define LOG_LOCAL5 (21<<3)
+#define LOG_LOCAL6 (22<<3)
+#define LOG_LOCAL7 (23<<3)
-#define LOG_FACMASK 01770
+#define LOG_NFACILITIES 24
+#define LOG_FACMASK 0x3f8
#define LOG_FAC(x) (((x) >> 3) & (LOG_FACMASK >> 3))
#define LOG_MASK(pri) (1 << (pri))
@@ -86,14 +87,10 @@
#define LOG_PERROR 0x20
void closelog(void);
-void openlog(const char* _Nullable, int, int);
-int setlogmask(int);
-void syslog(int, const char* _Nonnull, ...) __printflike(2, 3);
-#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
-void vsyslog(int, const char* _Nonnull, va_list) __printflike(2, 0);
-#else /* defined(__mips__) || defined(__i386__) */
-void vsyslog(int, const char* _Nonnull, va_list _Nonnull) __printflike(2, 0);
-#endif
+void openlog(const char* __prefix, int __option, int __facility);
+int setlogmask(int __mask);
+void syslog(int __priority, const char* __fmt, ...) __printflike(2, 3);
+void vsyslog(int __priority, const char* __fmt, va_list __args) __printflike(2, 0);
__END_DECLS
diff --git a/libc/include/termios.h b/libc/include/termios.h
index 66ae71c..3eaab00 100644
--- a/libc/include/termios.h
+++ b/libc/include/termios.h
@@ -37,23 +37,23 @@
#if __ANDROID_API__ >= __ANDROID_API_L__
// Implemented as static inlines before 21.
-speed_t cfgetispeed(const struct termios*) __INTRODUCED_IN(21);
-speed_t cfgetospeed(const struct termios*) __INTRODUCED_IN(21);
-void cfmakeraw(struct termios*) __INTRODUCED_IN(21);
-int cfsetspeed(struct termios*, speed_t) __INTRODUCED_IN(21);
-int cfsetispeed(struct termios*, speed_t) __INTRODUCED_IN(21);
-int cfsetospeed(struct termios*, speed_t) __INTRODUCED_IN(21);
-int tcdrain(int) __INTRODUCED_IN(21);
-int tcflow(int, int) __INTRODUCED_IN(21);
-int tcflush(int, int) __INTRODUCED_IN(21);
-int tcgetattr(int, struct termios*) __INTRODUCED_IN(21);
-pid_t tcgetsid(int) __INTRODUCED_IN(21);
-int tcsendbreak(int, int) __INTRODUCED_IN(21);
-int tcsetattr(int, int, const struct termios*) __INTRODUCED_IN(21);
+speed_t cfgetispeed(const struct termios* __t) __INTRODUCED_IN(21);
+speed_t cfgetospeed(const struct termios* __t) __INTRODUCED_IN(21);
+void cfmakeraw(struct termios* __t) __INTRODUCED_IN(21);
+int cfsetspeed(struct termios* __t, speed_t __speed) __INTRODUCED_IN(21);
+int cfsetispeed(struct termios* __t, speed_t __speed) __INTRODUCED_IN(21);
+int cfsetospeed(struct termios* __t, speed_t __speed) __INTRODUCED_IN(21);
+int tcdrain(int __fd) __INTRODUCED_IN(21);
+int tcflow(int __fd, int __action) __INTRODUCED_IN(21);
+int tcflush(int __fd, int __queue) __INTRODUCED_IN(21);
+int tcgetattr(int __fd, struct termios* __t) __INTRODUCED_IN(21);
+pid_t tcgetsid(int __fd) __INTRODUCED_IN(21);
+int tcsendbreak(int __fd, int __duration) __INTRODUCED_IN(21);
+int tcsetattr(int __fd, int __optional_actions, const struct termios* __t) __INTRODUCED_IN(21);
#endif
__END_DECLS
#include <android/legacy_termios_inlines.h>
-#endif /* _TERMIOS_H_ */
+#endif
diff --git a/libc/include/time.h b/libc/include/time.h
index 9fde77e..8e78949 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -59,54 +59,54 @@
#define TM_ZONE tm_zone
-time_t time(time_t*);
-int nanosleep(const struct timespec*, struct timespec*);
+time_t time(time_t* __t);
+int nanosleep(const struct timespec* __request, struct timespec* __remainder);
-char* asctime(const struct tm*);
-char* asctime_r(const struct tm*, char*);
+char* asctime(const struct tm* __tm);
+char* asctime_r(const struct tm* __tm, char* __buf);
-double difftime(time_t, time_t);
-time_t mktime(struct tm*);
+double difftime(time_t __lhs, time_t __rhs);
+time_t mktime(struct tm* __tm);
-struct tm* localtime(const time_t*);
-struct tm* localtime_r(const time_t*, struct tm*);
+struct tm* localtime(const time_t* __t);
+struct tm* localtime_r(const time_t* __t, struct tm* __tm);
-struct tm* gmtime(const time_t*);
-struct tm* gmtime_r(const time_t*, struct tm*);
+struct tm* gmtime(const time_t* __t);
+struct tm* gmtime_r(const time_t* __t, struct tm* __tm);
-char* strptime(const char*, const char*, struct tm*);
-size_t strftime(char*, size_t, const char*, const struct tm*);
+char* strptime(const char* __s, const char* __fmt, struct tm* __tm);
+size_t strftime(char* __buf, size_t __n, const char* __fmt, const struct tm* __tm);
#if __ANDROID_API__ >= __ANDROID_API_L__
-size_t strftime_l(char*, size_t, const char*, const struct tm*, locale_t) __INTRODUCED_IN(21);
+size_t strftime_l(char* __buf, size_t __n, const char* __fmt, const struct tm* __tm, locale_t __l) __INTRODUCED_IN(21);
#else
// Implemented as static inline before 21.
#endif
-char* ctime(const time_t*);
-char* ctime_r(const time_t*, char*);
+char* ctime(const time_t* __t);
+char* ctime_r(const time_t* __t, char* __buf);
void tzset(void);
clock_t clock(void);
-int clock_getcpuclockid(pid_t, clockid_t*) __INTRODUCED_IN(23);
+int clock_getcpuclockid(pid_t __pid, clockid_t* __clock) __INTRODUCED_IN(23);
-int clock_getres(clockid_t, struct timespec*);
-int clock_gettime(clockid_t, struct timespec*);
-int clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*);
-int clock_settime(clockid_t, const struct timespec*);
+int clock_getres(clockid_t __clock, struct timespec* __resolution);
+int clock_gettime(clockid_t __clock, struct timespec* __ts);
+int clock_nanosleep(clockid_t __clock, int __flags, const struct timespec* __request, struct timespec* __remainder);
+int clock_settime(clockid_t __clock, const struct timespec* __ts);
-int timer_create(int, struct sigevent*, timer_t*);
-int timer_delete(timer_t);
-int timer_settime(timer_t, int, const struct itimerspec*, struct itimerspec*);
-int timer_gettime(timer_t, struct itimerspec*);
-int timer_getoverrun(timer_t);
+int timer_create(clockid_t __clock, struct sigevent* __event, timer_t* __timer_ptr);
+int timer_delete(timer_t __timer);
+int timer_settime(timer_t __timer, int __flags, const struct itimerspec* __new_value, struct itimerspec* __old_value);
+int timer_gettime(timer_t __timer, struct itimerspec* __ts);
+int timer_getoverrun(timer_t __timer);
/* Non-standard extensions that are in the BSDs and glibc. */
-time_t timelocal(struct tm*) __INTRODUCED_IN(12);
-time_t timegm(struct tm*) __INTRODUCED_IN(12);
+time_t timelocal(struct tm* __tm) __INTRODUCED_IN(12);
+time_t timegm(struct tm* __tm) __INTRODUCED_IN(12);
__END_DECLS
-#endif /* _TIME_H_ */
+#endif
diff --git a/libc/include/uchar.h b/libc/include/uchar.h
index 818acb1..e59d6a9 100644
--- a/libc/include/uchar.h
+++ b/libc/include/uchar.h
@@ -43,13 +43,11 @@
#define __STD_UTF_16__ 1
#define __STD_UTF_32__ 1
-size_t c16rtomb(char* __restrict, char16_t, mbstate_t* __restrict) __INTRODUCED_IN(21);
-size_t c32rtomb(char* __restrict, char32_t, mbstate_t* __restrict) __INTRODUCED_IN(21);
-size_t mbrtoc16(char16_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict)
- __INTRODUCED_IN(21);
-size_t mbrtoc32(char32_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict)
- __INTRODUCED_IN(21);
+size_t c16rtomb(char* __buf, char16_t __ch16, mbstate_t* __ps) __INTRODUCED_IN(21);
+size_t c32rtomb(char* __buf, char32_t __ch32, mbstate_t* __ps) __INTRODUCED_IN(21);
+size_t mbrtoc16(char16_t* __ch16, const char* __s, size_t __n, mbstate_t* __ps) __INTRODUCED_IN(21);
+size_t mbrtoc32(char32_t* __ch32, const char* __s, size_t __n, mbstate_t* __ps) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* _UCHAR_H_ */
+#endif
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index e024527..9cfb918 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -118,39 +118,41 @@
int getresuid(uid_t* __ruid, uid_t* __euid, uid_t* __suid);
int getresgid(gid_t* __rgid, gid_t* __egid, gid_t* __sgid);
char* getlogin(void);
+int getlogin_r(char* __buffer, size_t __buffer_size) __INTRODUCED_IN_FUTURE;
long fpathconf(int __fd, int __name);
long pathconf(const char* __path, int __name);
int access(const char* __path, int __mode);
int faccessat(int __dirfd, const char* __path, int __mode, int __flags) __INTRODUCED_IN(16);
-int link(const char* __oldpath, const char* __newpath);
-int linkat(int __olddirfd, const char* __oldpath, int __newdirfd,
- const char* __newpath, int __flags) __INTRODUCED_IN(21);
+int link(const char* __old_path, const char* __new_path);
+int linkat(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path, int __flags) __INTRODUCED_IN(21);
int unlink(const char* __path);
int unlinkat(int __dirfd, const char* __path, int __flags);
int chdir(const char* __path);
int fchdir(int __fd);
int rmdir(const char* __path);
-int pipe(int* __pipefd);
+int pipe(int __fds[2]);
#if defined(__USE_GNU)
-int pipe2(int* __pipefd, int __flags) __INTRODUCED_IN(9);
+int pipe2(int __fds[2], int __flags) __INTRODUCED_IN(9);
#endif
int chroot(const char* __path);
-int symlink(const char* __oldpath, const char* __newpath);
-int symlinkat(const char* __oldpath, int __newdirfd, const char* __newpath) __INTRODUCED_IN(21);
-ssize_t readlink(const char* __path, char* __buf, size_t __bufsiz)
+int symlink(const char* __old_path, const char* __new_path);
+int symlinkat(const char* __old_path, int __new_dir_fd, const char* __new_path) __INTRODUCED_IN(21);
+ssize_t readlink(const char* __path, char* __buf, size_t __buf_size)
__overloadable __RENAME_CLANG(readlink);
-ssize_t readlinkat(int __dirfd, const char* __path, char* __buf,
- size_t __bufsiz)
+ssize_t readlinkat(int __dir_fd, const char* __path, char* __buf, size_t __buf_size)
__INTRODUCED_IN(21) __overloadable __RENAME_CLANG(readlinkat);
int chown(const char* __path, uid_t __owner, gid_t __group);
int fchown(int __fd, uid_t __owner, gid_t __group);
-int fchownat(int __dirfd, const char* __path, uid_t __owner, gid_t __group, int __flags);
+int fchownat(int __dir_fd, const char* __path, uid_t __owner, gid_t __group, int __flags);
int lchown(const char* __path, uid_t __owner, gid_t __group);
char* getcwd(char* __buf, size_t __size) __overloadable __RENAME_CLANG(getcwd);
void sync(void);
+#if defined(__USE_GNU)
+int syncfs(int __fd) __INTRODUCED_IN_FUTURE;
+#endif
int close(int __fd);
@@ -159,9 +161,9 @@
ssize_t write(int __fd, const void* __buf, size_t __count) __overloadable
__RENAME_CLANG(write);
-int dup(int __oldfd);
-int dup2(int __oldfd, int __newfd);
-int dup3(int __oldfd, int __newfd, int __flags) __INTRODUCED_IN(21);
+int dup(int __old_fd);
+int dup2(int __old_fd, int __new_fd);
+int dup3(int __old_fd, int __new_fd, int __flags) __INTRODUCED_IN(21);
int fsync(int __fd);
int fdatasync(int __fd) __INTRODUCED_IN(9);
@@ -199,19 +201,19 @@
int pause(void);
unsigned int alarm(unsigned int __seconds);
unsigned int sleep(unsigned int __seconds);
-int usleep(useconds_t __usec);
+int usleep(useconds_t __microseconds);
-int gethostname(char* __name, size_t __len);
-int sethostname(const char* __name, size_t __len) __INTRODUCED_IN(23);
+int gethostname(char* __buf, size_t __buf_size);
+int sethostname(const char* __name, size_t __n) __INTRODUCED_IN(23);
int brk(void* __addr);
void* sbrk(ptrdiff_t __increment);
int isatty(int __fd);
char* ttyname(int __fd);
-int ttyname_r(int __fd, char* __buf, size_t __buflen) __INTRODUCED_IN(8);
+int ttyname_r(int __fd, char* __buf, size_t __buf_size) __INTRODUCED_IN(8);
-int acct(const char* __filepath);
+int acct(const char* __path);
#if __ANDROID_API__ >= __ANDROID_API_L__
int getpagesize(void) __INTRODUCED_IN(21);
@@ -223,7 +225,7 @@
long syscall(long __number, ...);
-int daemon(int __nochdir, int __noclose);
+int daemon(int __no_chdir, int __no_close);
#if defined(__arm__) || (defined(__mips__) && !defined(__LP64__))
int cacheflush(long __addr, long __nbytes, long __cache);
@@ -241,505 +243,13 @@
} while (_rc == -1 && errno == EINTR); \
_rc; })
-/* TODO(unified-headers): Factor out all the FORTIFY features. */
-char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
+int getdomainname(char* __buf, size_t __buf_size) __INTRODUCED_IN(26);
+int setdomainname(const char* __name, size_t __n) __INTRODUCED_IN(26);
-ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
-ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
-
-ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
-ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12);
-
-ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
-ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
-
-ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
-ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64)
- __INTRODUCED_IN(12);
-
-ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
-ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
-ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
-ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
-
-int getdomainname(char*, size_t) __INTRODUCED_IN(26);
-int setdomainname(const char*, size_t) __INTRODUCED_IN(26);
-
-#if defined(__BIONIC_FORTIFY)
-
-#if defined(__USE_FILE_OFFSET64)
-#define __PREAD_PREFIX(x) __pread64_ ## x
-#define __PWRITE_PREFIX(x) __pwrite64_ ## x
-#else
-#define __PREAD_PREFIX(x) __pread_ ## x
-#define __PWRITE_PREFIX(x) __pwrite_ ## x
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/unistd.h>
#endif
-#if defined(__clang__)
-#define __error_if_overflows_ssizet(what) \
- __enable_if(what > SSIZE_MAX, #what " must be <= SSIZE_MAX") \
- __errorattr(#what " must be <= SSIZE_MAX")
-
-#define __enable_if_no_overflow_ssizet(what) \
- __enable_if((what) <= SSIZE_MAX, "enabled if " #what " <= SSIZE_MAX")
-
-#define __error_if_overflows_objectsize(what, objsize) \
- __enable_if((objsize) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
- (what) > (objsize), \
- "'" #what "' bytes overflows the given object") \
- __errorattr("'" #what "' bytes overflows the given object")
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char* getcwd(char* buf, size_t size) __overloadable
- __error_if_overflows_objectsize(size, __bos(buf));
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-char* getcwd(char* const __pass_object_size buf, size_t size) __overloadable {
- size_t bos = __bos(buf);
-
- /*
- * Clang responds bos==0 if buf==NULL
- * (https://llvm.org/bugs/show_bug.cgi?id=23277). Given that NULL is a valid
- * value, we need to handle that.
- */
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE || buf == NULL) {
- return __call_bypassing_fortify(getcwd)(buf, size);
- }
-
- return __getcwd_chk(buf, size, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pread(int fd, void* buf, size_t count, off_t offset) __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pread(int fd, void* buf, size_t count, off_t offset) __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count,
- off_t offset) __overloadable {
- size_t bos = __bos0(buf);
-
- if (count == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __PREAD_PREFIX(real)(fd, buf, count, offset);
- }
-
- return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count,
- off64_t offset) __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __pread64_real(fd, buf, count, offset);
- }
-
- return __pread64_chk(fd, buf, count, offset, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset)
- __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset)
- __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count,
- off_t offset) __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __PWRITE_PREFIX(real)(fd, buf, count, offset);
- }
-
- return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset)
- __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset)
- __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf,
- size_t count, off64_t offset) __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __pwrite64_real(fd, buf, count, offset);
- }
-
- return __pwrite64_chk(fd, buf, count, offset, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t read(int fd, void* buf, size_t count) __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t read(int fd, void* buf, size_t count) __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
- __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(read)(fd, buf, count);
- }
-
- return __read_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t write(int fd, const void* buf, size_t count) __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t write(int fd, const void* buf, size_t count) __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
- __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(write)(fd, buf, count);
- }
-
- return __write_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t readlink(const char* path, char* buf, size_t size) __overloadable
- __error_if_overflows_ssizet(size);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t readlink(const char* path, char* buf, size_t size) __overloadable
- __enable_if_no_overflow_ssizet(size)
- __error_if_overflows_objectsize(size, __bos(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t readlink(const char* path, char* const __pass_object_size buf,
- size_t size) __overloadable {
- size_t bos = __bos(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(readlink)(path, buf, size);
- }
-
- return __readlink_chk(path, buf, size, bos);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size)
- __overloadable
- __error_if_overflows_ssizet(size);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size)
- __overloadable
- __enable_if_no_overflow_ssizet(size)
- __error_if_overflows_objectsize(size, __bos(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t readlinkat(int dirfd, const char* path,
- char* const __pass_object_size buf, size_t size)
- __overloadable {
- size_t bos = __bos(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(readlinkat)(dirfd, path, buf, size);
- }
-
- return __readlinkat_chk(dirfd, path, buf, size, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#undef __enable_if_no_overflow_ssizet
-#undef __error_if_overflows_objectsize
-#undef __error_if_overflows_ssizet
-#else /* defined(__clang__) */
-
-char* __getcwd_real(char*, size_t) __RENAME(getcwd);
-ssize_t __read_real(int, void*, size_t) __RENAME(read);
-ssize_t __write_real(int, const void*, size_t) __RENAME(write);
-ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);
-ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat);
-
-__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination");
-__errordecl(__pread_dest_size_error, "pread called with size bigger than destination");
-__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX");
-__errordecl(__pread64_dest_size_error, "pread64 called with size bigger than destination");
-__errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX");
-__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination");
-__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX");
-__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination");
-__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX");
-__errordecl(__read_dest_size_error, "read called with size bigger than destination");
-__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX");
-__errordecl(__write_dest_size_error, "write called with size bigger than destination");
-__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX");
-__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination");
-__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX");
-__errordecl(__readlinkat_dest_size_error, "readlinkat called with size bigger than destination");
-__errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX");
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-char* getcwd(char* buf, size_t size) __overloadable {
- size_t bos = __bos(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __getcwd_real(buf, size);
- }
-
- if (__builtin_constant_p(size) && (size > bos)) {
- __getcwd_dest_size_error();
- }
-
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __getcwd_real(buf, size);
- }
-
- return __getcwd_chk(buf, size, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_FORTIFY_INLINE
-ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __PREAD_PREFIX(count_toobig_error)();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __PREAD_PREFIX(real)(fd, buf, count, offset);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __PREAD_PREFIX(dest_size_error)();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __PREAD_PREFIX(real)(fd, buf, count, offset);
- }
-
- return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __pread64_count_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __pread64_real(fd, buf, count, offset);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __pread64_dest_size_error();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __pread64_real(fd, buf, count, offset);
- }
-
- return __pread64_chk(fd, buf, count, offset, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __PWRITE_PREFIX(count_toobig_error)();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __PWRITE_PREFIX(real)(fd, buf, count, offset);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __PWRITE_PREFIX(dest_size_error)();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __PWRITE_PREFIX(real)(fd, buf, count, offset);
- }
-
- return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __pwrite64_count_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __pwrite64_real(fd, buf, count, offset);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __pwrite64_dest_size_error();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __pwrite64_real(fd, buf, count, offset);
- }
-
- return __pwrite64_chk(fd, buf, count, offset, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_FORTIFY_INLINE
-ssize_t read(int fd, void* buf, size_t count) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __read_count_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __read_real(fd, buf, count);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __read_dest_size_error();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __read_real(fd, buf, count);
- }
-
- return __read_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-ssize_t write(int fd, const void* buf, size_t count) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __write_real(fd, buf, count);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __write_dest_size_error();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __write_real(fd, buf, count);
- }
-
- return __write_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_FORTIFY_INLINE
-ssize_t readlink(const char* path, char* buf, size_t size) {
- size_t bos = __bos(buf);
-
- if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
- __readlink_size_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __readlink_real(path, buf, size);
- }
-
- if (__builtin_constant_p(size) && (size > bos)) {
- __readlink_dest_size_error();
- }
-
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __readlink_real(path, buf, size);
- }
-
- return __readlink_chk(path, buf, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {
- size_t bos = __bos(buf);
-
- if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
- __readlinkat_size_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __readlinkat_real(dirfd, path, buf, size);
- }
-
- if (__builtin_constant_p(size) && (size > bos)) {
- __readlinkat_dest_size_error();
- }
-
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __readlinkat_real(dirfd, path, buf, size);
- }
-
- return __readlinkat_chk(dirfd, path, buf, size, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-#endif /* defined(__clang__) */
-#undef __PREAD_PREFIX
-#undef __PWRITE_PREFIX
-#endif /* defined(__BIONIC_FORTIFY) */
-
__END_DECLS
#endif /* _UNISTD_H_ */
diff --git a/libc/include/utime.h b/libc/include/utime.h
index 9783859..be6b894 100644
--- a/libc/include/utime.h
+++ b/libc/include/utime.h
@@ -35,8 +35,8 @@
__BEGIN_DECLS
-int utime(const char*, const struct utimbuf*);
+int utime(const char* __filename, const struct utimbuf* __times);
__END_DECLS
-#endif /* _UTIME_H_ */
+#endif
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index 62e8d59..6a52511 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -96,12 +96,12 @@
__BEGIN_DECLS
-int utmpname(const char*);
+int utmpname(const char* __path);
void setutent(void);
struct utmp* getutent(void);
void endutent(void);
-int login_tty(int) __INTRODUCED_IN(23);
+int login_tty(int __fd) __INTRODUCED_IN(23);
__END_DECLS
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index c9a78be..1dda4bd 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _WCHAR_H_
#define _WCHAR_H_
@@ -42,98 +43,98 @@
__BEGIN_DECLS
-wint_t btowc(int);
-int fwprintf(FILE *, const wchar_t *, ...);
-int fwscanf(FILE *, const wchar_t *, ...);
-wint_t fgetwc(FILE *);
-wchar_t *fgetws(wchar_t *, int, FILE *);
-wint_t fputwc(wchar_t, FILE *);
-int fputws(const wchar_t *, FILE *);
-int fwide(FILE *, int);
-wint_t getwc(FILE *);
-wint_t getwchar(void);
-int mbsinit(const mbstate_t *);
-size_t mbrlen(const char *, size_t, mbstate_t *);
-size_t mbrtowc(wchar_t *, const char *, size_t, mbstate_t *);
-size_t mbsrtowcs(wchar_t*, const char**, size_t, mbstate_t*);
-size_t mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*) __INTRODUCED_IN(21);
-wint_t putwc(wchar_t, FILE *);
-wint_t putwchar(wchar_t);
-int swprintf(wchar_t *, size_t, const wchar_t *, ...);
-int swscanf(const wchar_t *, const wchar_t *, ...);
-wint_t ungetwc(wint_t, FILE *);
-int vfwprintf(FILE*, const wchar_t*, va_list);
-int vfwscanf(FILE*, const wchar_t*, va_list) __INTRODUCED_IN(21);
-int vswprintf(wchar_t*, size_t, const wchar_t*, va_list);
-int vswscanf(const wchar_t*, const wchar_t*, va_list) __INTRODUCED_IN(21);
-int vwprintf(const wchar_t*, va_list);
-int vwscanf(const wchar_t*, va_list) __INTRODUCED_IN(21);
-wchar_t* wcpcpy (wchar_t*, const wchar_t *);
-wchar_t* wcpncpy (wchar_t*, const wchar_t *, size_t);
-size_t wcrtomb(char *, wchar_t, mbstate_t *);
-int wcscasecmp(const wchar_t *, const wchar_t *);
-int wcscasecmp_l(const wchar_t*, const wchar_t*, locale_t) __INTRODUCED_IN(23);
-wchar_t *wcscat(wchar_t *, const wchar_t *);
-wchar_t *wcschr(const wchar_t *, wchar_t);
-int wcscmp(const wchar_t *, const wchar_t *);
-int wcscoll(const wchar_t *, const wchar_t *);
-wchar_t *wcscpy(wchar_t *, const wchar_t *);
-size_t wcscspn(const wchar_t *, const wchar_t *);
-size_t wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *);
-size_t wcslen(const wchar_t *);
-int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
-int wcsncasecmp_l(const wchar_t*, const wchar_t*, size_t, locale_t) __INTRODUCED_IN(23);
-wchar_t *wcsncat(wchar_t *, const wchar_t *, size_t);
-int wcsncmp(const wchar_t *, const wchar_t *, size_t);
-wchar_t *wcsncpy(wchar_t *, const wchar_t *, size_t);
-size_t wcsnrtombs(char*, const wchar_t**, size_t, size_t, mbstate_t*) __INTRODUCED_IN(21);
-wchar_t *wcspbrk(const wchar_t *, const wchar_t *);
-wchar_t *wcsrchr(const wchar_t *, wchar_t);
-size_t wcsrtombs(char*, const wchar_t**, size_t, mbstate_t*);
-size_t wcsspn(const wchar_t *, const wchar_t *);
-wchar_t *wcsstr(const wchar_t *, const wchar_t *);
-double wcstod(const wchar_t*, wchar_t**);
-float wcstof(const wchar_t*, wchar_t**) __INTRODUCED_IN(21);
-wchar_t* wcstok(wchar_t*, const wchar_t*, wchar_t**);
-long wcstol(const wchar_t*, wchar_t**, int);
-long long wcstoll(const wchar_t*, wchar_t**, int) __INTRODUCED_IN(21);
-long double wcstold(const wchar_t*, wchar_t**) __INTRODUCED_IN(21);
-unsigned long wcstoul(const wchar_t*, wchar_t**, int);
-unsigned long long wcstoull(const wchar_t*, wchar_t**, int) __INTRODUCED_IN(21);
-int wcswidth(const wchar_t *, size_t);
-size_t wcsxfrm(wchar_t *, const wchar_t *, size_t);
-int wctob(wint_t);
-int wcwidth(wchar_t);
-wchar_t *wmemchr(const wchar_t *, wchar_t, size_t);
-int wmemcmp(const wchar_t *, const wchar_t *, size_t);
-wchar_t *wmemcpy(wchar_t *, const wchar_t *, size_t);
+wint_t btowc(int __ch);
+int fwprintf(FILE* __fp, const wchar_t* __fmt, ...);
+int fwscanf(FILE* __fp, const wchar_t* __fmt, ...);
+wint_t fgetwc(FILE* __fp);
+wchar_t* fgetws(wchar_t* __buf, int __size, FILE* __fp);
+wint_t fputwc(wchar_t __wc, FILE* __fp);
+int fputws(const wchar_t* __s, FILE* __fp);
+int fwide(FILE* __fp, int __mode);
+wint_t getwc(FILE* __fp);
+wint_t getwchar(void);
+int mbsinit(const mbstate_t* __ps);
+size_t mbrlen(const char* __s, size_t __n, mbstate_t* __ps);
+size_t mbrtowc(wchar_t* __buf, const char* __s, size_t __n, mbstate_t* __ps);
+size_t mbsrtowcs(wchar_t* __dst, const char** __src, size_t __dst_n, mbstate_t* __ps);
+size_t mbsnrtowcs(wchar_t* __dst, const char** __src, size_t __src_n, size_t __dst_n, mbstate_t* __ps) __INTRODUCED_IN(21);
+wint_t putwc(wchar_t __wc, FILE* __fp);
+wint_t putwchar(wchar_t __wc);
+int swprintf(wchar_t* __buf, size_t __n, const wchar_t* __fmt, ...);
+int swscanf(const wchar_t* __s, const wchar_t* __fmt, ...);
+wint_t ungetwc(wint_t __wc, FILE* __fp);
+int vfwprintf(FILE* __fp, const wchar_t* __fmt, va_list __args);
+int vfwscanf(FILE* __fp, const wchar_t* __fmt, va_list __args) __INTRODUCED_IN(21);
+int vswprintf(wchar_t* __buf, size_t __n, const wchar_t* __fmt, va_list __args);
+int vswscanf(const wchar_t* __s, const wchar_t* __fmt, va_list __args) __INTRODUCED_IN(21);
+int vwprintf(const wchar_t* __fmt, va_list __args);
+int vwscanf(const wchar_t* __fmt, va_list __args) __INTRODUCED_IN(21);
+wchar_t* wcpcpy(wchar_t* __dst, const wchar_t* __src);
+wchar_t* wcpncpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
+size_t wcrtomb(char* __buf, wchar_t __wc, mbstate_t* __ps);
+int wcscasecmp(const wchar_t* __lhs, const wchar_t* __rhs);
+int wcscasecmp_l(const wchar_t* __lhs, const wchar_t* __rhs, locale_t __l) __INTRODUCED_IN(23);
+wchar_t* wcscat(wchar_t* __dst, const wchar_t* __src);
+wchar_t* wcschr(const wchar_t* __s, wchar_t __wc);
+int wcscmp(const wchar_t* __lhs, const wchar_t* __rhs);
+int wcscoll(const wchar_t* __lhs, const wchar_t* __rhs);
+wchar_t* wcscpy(wchar_t* __dst, const wchar_t* __src);
+size_t wcscspn(const wchar_t* __s, const wchar_t* __accept);
+size_t wcsftime(wchar_t* __buf, size_t __n, const wchar_t* __fmt, const struct tm* __tm);
+size_t wcslen(const wchar_t* __s);
+int wcsncasecmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
+int wcsncasecmp_l(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n, locale_t __l) __INTRODUCED_IN(23);
+wchar_t* wcsncat(wchar_t* __dst, const wchar_t* __src, size_t __n);
+int wcsncmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
+wchar_t* wcsncpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
+size_t wcsnrtombs(char* __dst, const wchar_t** __src, size_t __src_n, size_t __dst_n, mbstate_t* __ps) __INTRODUCED_IN(21);
+wchar_t* wcspbrk(const wchar_t* __s, const wchar_t* __accept);
+wchar_t* wcsrchr(const wchar_t* __s, wchar_t __wc);
+size_t wcsrtombs(char* __dst, const wchar_t** __src, size_t __dst_n, mbstate_t* __ps);
+size_t wcsspn(const wchar_t* __s, const wchar_t* __accept);
+wchar_t* wcsstr(const wchar_t* __haystack, const wchar_t* __needle);
+double wcstod(const wchar_t* __s, wchar_t** __end_ptr);
+float wcstof(const wchar_t* __s, wchar_t** __end_ptr) __INTRODUCED_IN(21);
+wchar_t* wcstok(wchar_t* __s, const wchar_t* __delimiter, wchar_t** __ptr);
+long wcstol(const wchar_t* __s, wchar_t** __end_ptr, int __base);
+long long wcstoll(const wchar_t* __s, wchar_t** __end_ptr, int __base) __INTRODUCED_IN(21);
+long double wcstold(const wchar_t* __s, wchar_t** __end_ptr) __INTRODUCED_IN(21);
+unsigned long wcstoul(const wchar_t* __s, wchar_t** __end_ptr, int __base);
+unsigned long long wcstoull(const wchar_t* __s, wchar_t** __end_ptr, int __base) __INTRODUCED_IN(21);
+int wcswidth(const wchar_t* __s, size_t __n);
+size_t wcsxfrm(wchar_t* __dst, const wchar_t* __src, size_t __n);
+int wctob(wint_t __wc);
+int wcwidth(wchar_t __wc);
+wchar_t* wmemchr(const wchar_t* __src, wchar_t __wc, size_t __n);
+int wmemcmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
+wchar_t* wmemcpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
#if defined(__USE_GNU)
-wchar_t* wmempcpy(wchar_t*, const wchar_t*, size_t) __INTRODUCED_IN(23);
+wchar_t* wmempcpy(wchar_t* __dst, const wchar_t* __src, size_t __n) __INTRODUCED_IN(23);
#endif
-wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t);
-wchar_t *wmemset(wchar_t *, wchar_t, size_t);
-int wprintf(const wchar_t *, ...);
-int wscanf(const wchar_t *, ...);
+wchar_t* wmemmove(wchar_t* __dst, const wchar_t* __src, size_t __n);
+wchar_t* wmemset(wchar_t* __dst, wchar_t __wc, size_t __n);
+int wprintf(const wchar_t* __fmt, ...);
+int wscanf(const wchar_t* __fmt, ...);
#if __ANDROID_API__ >= __ANDROID_API_L__
-long long wcstoll_l(const wchar_t*, wchar_t**, int, locale_t) __INTRODUCED_IN(21);
-unsigned long long wcstoull_l(const wchar_t*, wchar_t**, int, locale_t) __INTRODUCED_IN(21);
-long double wcstold_l(const wchar_t*, wchar_t**, locale_t) __INTRODUCED_IN(21);
+long long wcstoll_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
+unsigned long long wcstoull_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
+long double wcstold_l(const wchar_t* __s, wchar_t** __end_ptr, locale_t __l) __INTRODUCED_IN(21);
-int wcscoll_l(const wchar_t* _Nonnull, const wchar_t* _Nonnull, locale_t) __attribute_pure__
+int wcscoll_l(const wchar_t* __lhs, const wchar_t* __rhs, locale_t __l) __attribute_pure__
__INTRODUCED_IN(21);
-size_t wcsxfrm_l(wchar_t*, const wchar_t* _Nonnull, size_t, locale_t) __INTRODUCED_IN(21);
+size_t wcsxfrm_l(wchar_t* __dst, const wchar_t* __src, size_t __n, locale_t __l) __INTRODUCED_IN(21);
#else
// Implemented as static inlines before 21.
#endif
-size_t wcslcat(wchar_t*, const wchar_t*, size_t);
-size_t wcslcpy(wchar_t*, const wchar_t*, size_t);
+size_t wcslcat(wchar_t* __dst, const wchar_t* __src, size_t __n);
+size_t wcslcpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
-FILE* open_wmemstream(wchar_t**, size_t*) __INTRODUCED_IN(23);
-wchar_t* wcsdup(const wchar_t*);
-size_t wcsnlen(const wchar_t*, size_t);
+FILE* open_wmemstream(wchar_t** __ptr, size_t* __size_ptr) __INTRODUCED_IN(23);
+wchar_t* wcsdup(const wchar_t* __s);
+size_t wcsnlen(const wchar_t* __s, size_t __n);
__END_DECLS
-#endif /* _WCHAR_H_ */
+#endif
diff --git a/libc/include/wctype.h b/libc/include/wctype.h
index 39e34f6..18f5c4b 100644
--- a/libc/include/wctype.h
+++ b/libc/include/wctype.h
@@ -36,31 +36,31 @@
__BEGIN_DECLS
#if __ANDROID_API__ >= __ANDROID_API_L__
-int iswalnum_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswalpha_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswblank_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswcntrl_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswdigit_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswgraph_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswlower_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswprint_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswpunct_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswspace_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswupper_l(wint_t, locale_t) __INTRODUCED_IN(21);
-int iswxdigit_l(wint_t, locale_t) __INTRODUCED_IN(21);
+int iswalnum_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswalpha_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswblank_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswcntrl_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswdigit_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswgraph_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswlower_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswprint_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswpunct_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswspace_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswupper_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+int iswxdigit_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
-wint_t towlower_l(wint_t, locale_t) __INTRODUCED_IN(21);
-wint_t towupper_l(wint_t, locale_t) __INTRODUCED_IN(21);
+wint_t towlower_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
+wint_t towupper_l(wint_t __wc, locale_t __l) __INTRODUCED_IN(21);
#else
// Implemented as static inlines before 21.
#endif
-wint_t towctrans_l(wint_t, wctrans_t, locale_t) __INTRODUCED_IN(26);
-wctrans_t wctrans_l(const char*, locale_t) __INTRODUCED_IN(26);
+wint_t towctrans_l(wint_t __wc, wctrans_t __transform, locale_t __l) __INTRODUCED_IN(26);
+wctrans_t wctrans_l(const char* __name, locale_t __l) __INTRODUCED_IN(26);
-wctype_t wctype_l(const char*, locale_t) __INTRODUCED_IN(21);
-int iswctype_l(wint_t, wctype_t, locale_t) __INTRODUCED_IN(21);
+wctype_t wctype_l(const char* __name, locale_t __l) __INTRODUCED_IN(21);
+int iswctype_l(wint_t __wc, wctype_t __transform, locale_t __l) __INTRODUCED_IN(21);
__END_DECLS
-#endif /* _WCTYPE_H_ */
+#endif
diff --git a/libc/kernel/android/scsi/scsi/scsi_proto.h b/libc/kernel/android/scsi/scsi/scsi_proto.h
index 2ebc5be..7f3abd9 100644
--- a/libc/kernel/android/scsi/scsi/scsi_proto.h
+++ b/libc/kernel/android/scsi/scsi/scsi_proto.h
@@ -115,6 +115,7 @@
#define WRITE_16 0x8a
#define READ_ATTRIBUTE 0x8c
#define WRITE_ATTRIBUTE 0x8d
+#define WRITE_VERIFY_16 0x8e
#define VERIFY_16 0x8f
#define SYNCHRONIZE_CACHE_16 0x91
#define WRITE_SAME_16 0x93
diff --git a/libc/kernel/android/scsi/scsi/sg.h b/libc/kernel/android/scsi/scsi/sg.h
index 29ea51e..828b2c6 100644
--- a/libc/kernel/android/scsi/scsi/sg.h
+++ b/libc/kernel/android/scsi/scsi/sg.h
@@ -113,7 +113,6 @@
#define SG_GET_ACCESS_COUNT 0x2289
#define SG_SCATTER_SZ (8 * 4096)
#define SG_DEFAULT_RETRIES 0
-#define SG_DEF_FORCE_LOW_DMA 0
#define SG_DEF_FORCE_PACK_ID 0
#define SG_DEF_KEEP_ORPHAN 0
#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 9612812..b0fb95f 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -84,6 +84,8 @@
"epoll_event": "__kernel_uapi_epoll_event",
# This causes problems when trying to export the headers for the ndk.
"__attribute_const__": "__attribute__((__const__))",
+ # There is a mismatch between upstream and our kernels for this structure.
+ "binder_fd_array_object": "__kernel_binder_fd_array_object",
}
# This is the set of known static inline functions that we want to keep
diff --git a/libc/kernel/uapi/asm-arm/asm/kvm.h b/libc/kernel/uapi/asm-arm/asm/kvm.h
index 1c28bce..c814a09 100644
--- a/libc/kernel/uapi/asm-arm/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm/asm/kvm.h
@@ -24,6 +24,7 @@
#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_READONLY_MEM
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_REG_SIZE(id) (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
#define KVM_ARM_SVC_sp svc_regs[0]
#define KVM_ARM_SVC_lr svc_regs[1]
@@ -86,6 +87,7 @@
struct kvm_debug_exit_arch {
};
struct kvm_sync_regs {
+ __u64 device_irq_level;
};
struct kvm_arch_memory_slot {
};
@@ -130,11 +132,25 @@
#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
#define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
#define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
+#define KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
+#define KVM_DEV_ARM_VGIC_V3_MPIDR_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
+#define KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff)
#define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
+#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
+#define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
+#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
+#define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK (0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff
+#define VGIC_LEVEL_INFO_LINE_LEVEL 0
#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
+#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
+#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
+#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
#define KVM_ARM_IRQ_TYPE_SHIFT 24
#define KVM_ARM_IRQ_TYPE_MASK 0xff
#define KVM_ARM_IRQ_VCPU_SHIFT 16
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-common.h b/libc/kernel/uapi/asm-arm/asm/unistd-common.h
index b2b6e94..c9ee555 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-common.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-common.h
@@ -370,4 +370,5 @@
#define __NR_pkey_mprotect (__NR_SYSCALL_BASE + 394)
#define __NR_pkey_alloc (__NR_SYSCALL_BASE + 395)
#define __NR_pkey_free (__NR_SYSCALL_BASE + 396)
+#define __NR_statx (__NR_SYSCALL_BASE + 397)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 6696ff0..4ab16ad 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -29,4 +29,9 @@
#define HWCAP_ATOMICS (1 << 8)
#define HWCAP_FPHP (1 << 9)
#define HWCAP_ASIMDHP (1 << 10)
+#define HWCAP_CPUID (1 << 11)
+#define HWCAP_ASIMDRDM (1 << 12)
+#define HWCAP_JSCVT (1 << 13)
+#define HWCAP_FCMA (1 << 14)
+#define HWCAP_LRCPC (1 << 15)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index 81de8a4..dade888 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -32,6 +32,7 @@
#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_READONLY_MEM
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_REG_SIZE(id) (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
struct kvm_regs {
struct user_pt_regs regs;
@@ -88,6 +89,7 @@
#define KVM_GUESTDBG_USE_SW_BP (1 << 16)
#define KVM_GUESTDBG_USE_HW (1 << 17)
struct kvm_sync_regs {
+ __u64 device_irq_level;
};
struct kvm_arch_memory_slot {
};
@@ -123,11 +125,25 @@
#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
#define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
#define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
+#define KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
+#define KVM_DEV_ARM_VGIC_V3_MPIDR_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
+#define KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff)
#define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
+#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
+#define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
+#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
+#define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK (0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
+#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff
+#define VGIC_LEVEL_INFO_LINE_LEVEL 0
#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
+#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
+#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
+#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
#define KVM_ARM_VCPU_PMU_V3_CTRL 0
#define KVM_ARM_VCPU_PMU_V3_IRQ 0
#define KVM_ARM_VCPU_PMU_V3_INIT 1
diff --git a/libc/kernel/uapi/asm-generic/socket.h b/libc/kernel/uapi/asm-generic/socket.h
index 2113896..d1dc0099 100644
--- a/libc/kernel/uapi/asm-generic/socket.h
+++ b/libc/kernel/uapi/asm-generic/socket.h
@@ -82,4 +82,7 @@
#define SO_ATTACH_REUSEPORT_EBPF 52
#define SO_CNX_ADVICE 53
#define SCM_TIMESTAMPING_OPT_STATS 54
+#define SO_MEMINFO 55
+#define SO_INCOMING_NAPI_ID 56
+#define SO_COOKIE 57
#endif
diff --git a/libc/kernel/uapi/asm-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index 4c9634f..83c41f9 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -96,7 +96,6 @@
#define __NR_pipe2 59
#define __NR_quotactl 60
#define __NR_getdents64 61
-#define __ARCH_WANT_COMPAT_SYS_GETDENTS64
#define __NR3264_lseek 62
#define __NR_read 63
#define __NR_write 64
@@ -317,8 +316,9 @@
#define __NR_pkey_mprotect 288
#define __NR_pkey_alloc 289
#define __NR_pkey_free 290
+#define __NR_statx 291
#undef __NR_syscalls
-#define __NR_syscalls 291
+#define __NR_syscalls 292
#ifdef __ARCH_WANT_SYSCALL_NO_AT
#define __NR_open 1024
#define __NR_link 1025
diff --git a/libc/kernel/uapi/asm-mips/asm/inst.h b/libc/kernel/uapi/asm-mips/asm/inst.h
index 6bf1f69..46a65e6 100644
--- a/libc/kernel/uapi/asm-mips/asm/inst.h
+++ b/libc/kernel/uapi/asm-mips/asm/inst.h
@@ -315,6 +315,7 @@
rfe_op = 0x10,
eret_op = 0x18,
wait_op = 0x20,
+ hypcall_op = 0x28
};
enum cop0_com_func {
tlbr1_op = 0x01,
diff --git a/libc/kernel/uapi/asm-mips/asm/kvm.h b/libc/kernel/uapi/asm-mips/asm/kvm.h
index cf4e012..c42ea8d 100644
--- a/libc/kernel/uapi/asm-mips/asm/kvm.h
+++ b/libc/kernel/uapi/asm-mips/asm/kvm.h
@@ -19,6 +19,8 @@
#ifndef __LINUX_KVM_MIPS_H
#define __LINUX_KVM_MIPS_H
#include <linux/types.h>
+#define __KVM_HAVE_READONLY_MEM
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
struct kvm_regs {
__u64 gpr[32];
__u64 hi;
@@ -66,6 +68,8 @@
#define KVM_REG_MIPS_HI (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 32)
#define KVM_REG_MIPS_LO (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 33)
#define KVM_REG_MIPS_PC (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 34)
+#define KVM_REG_MIPS_MAAR (KVM_REG_MIPS_CP0 | (1 << 8))
+#define KVM_REG_MIPS_CP0_MAAR(n) (KVM_REG_MIPS_MAAR | KVM_REG_SIZE_U64 | (n))
#define KVM_REG_MIPS_COUNT_CTL (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 0)
#define KVM_REG_MIPS_COUNT_CTL_DC 0x00000001
#define KVM_REG_MIPS_COUNT_RESUME (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 1)
diff --git a/libc/kernel/uapi/asm-mips/asm/socket.h b/libc/kernel/uapi/asm-mips/asm/socket.h
index a57a561..e97ae58 100644
--- a/libc/kernel/uapi/asm-mips/asm/socket.h
+++ b/libc/kernel/uapi/asm-mips/asm/socket.h
@@ -81,4 +81,7 @@
#define SO_ATTACH_REUSEPORT_EBPF 52
#define SO_CNX_ADVICE 53
#define SCM_TIMESTAMPING_OPT_STATS 54
+#define SO_MEMINFO 55
+#define SO_INCOMING_NAPI_ID 56
+#define SO_COOKIE 57
#endif
diff --git a/libc/kernel/uapi/asm-mips/asm/unistd.h b/libc/kernel/uapi/asm-mips/asm/unistd.h
index 11055c3..76d7b81 100644
--- a/libc/kernel/uapi/asm-mips/asm/unistd.h
+++ b/libc/kernel/uapi/asm-mips/asm/unistd.h
@@ -386,10 +386,11 @@
#define __NR_pkey_mprotect (__NR_Linux + 363)
#define __NR_pkey_alloc (__NR_Linux + 364)
#define __NR_pkey_free (__NR_Linux + 365)
-#define __NR_Linux_syscalls 365
+#define __NR_statx (__NR_Linux + 366)
+#define __NR_Linux_syscalls 366
#endif
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 365
+#define __NR_O32_Linux_syscalls 366
#if _MIPS_SIM == _MIPS_SIM_ABI64
#define __NR_Linux 5000
#define __NR_read (__NR_Linux + 0)
@@ -717,10 +718,11 @@
#define __NR_pkey_mprotect (__NR_Linux + 323)
#define __NR_pkey_alloc (__NR_Linux + 324)
#define __NR_pkey_free (__NR_Linux + 325)
-#define __NR_Linux_syscalls 325
+#define __NR_statx (__NR_Linux + 326)
+#define __NR_Linux_syscalls 326
#endif
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 325
+#define __NR_64_Linux_syscalls 326
#if _MIPS_SIM == _MIPS_SIM_NABI32
#define __NR_Linux 6000
#define __NR_read (__NR_Linux + 0)
@@ -1052,8 +1054,9 @@
#define __NR_pkey_mprotect (__NR_Linux + 327)
#define __NR_pkey_alloc (__NR_Linux + 328)
#define __NR_pkey_free (__NR_Linux + 329)
-#define __NR_Linux_syscalls 329
+#define __NR_statx (__NR_Linux + 330)
+#define __NR_Linux_syscalls 330
#endif
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 329
+#define __NR_N32_Linux_syscalls 330
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/bootparam.h b/libc/kernel/uapi/asm-x86/asm/bootparam.h
index d9421b7..772f552 100644
--- a/libc/kernel/uapi/asm-x86/asm/bootparam.h
+++ b/libc/kernel/uapi/asm-x86/asm/bootparam.h
@@ -42,7 +42,6 @@
#include <linux/screen_info.h>
#include <linux/apm_bios.h>
#include <linux/edd.h>
-#include <asm/e820.h>
#include <asm/ist.h>
#include <video/edid.h>
struct setup_data {
@@ -63,7 +62,7 @@
__u32 header;
__u16 version;
__u32 realmode_swtch;
- __u16 start_sys;
+ __u16 start_sys_seg;
__u16 kernel_version;
__u8 type_of_loader;
__u8 loadflags;
@@ -111,6 +110,12 @@
__u32 efi_systab_hi;
__u32 efi_memmap_hi;
};
+#define E820_MAX_ENTRIES_ZEROPAGE 128
+struct boot_e820_entry {
+ __u64 addr;
+ __u64 size;
+ __u32 type;
+} __attribute__((packed));
struct boot_params {
struct screen_info screen_info;
struct apm_bios_info apm_bios_info;
@@ -134,13 +139,14 @@
__u8 eddbuf_entries;
__u8 edd_mbr_sig_buf_entries;
__u8 kbd_status;
- __u8 _pad5[3];
+ __u8 secure_boot;
+ __u8 _pad5[2];
__u8 sentinel;
__u8 _pad6[1];
struct setup_header hdr;
__u8 _pad7[0x290 - 0x1f1 - sizeof(struct setup_header)];
__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];
- struct e820entry e820_map[E820MAX];
+ struct boot_e820_entry e820_table[E820_MAX_ENTRIES_ZEROPAGE];
__u8 _pad8[48];
struct edd_info eddbuf[EDDMAXNR];
__u8 _pad9[276];
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/asm-x86/asm/hwcap2.h
similarity index 67%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/asm-x86/asm/hwcap2.h
index 3064508..9015dee 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/asm-x86/asm/hwcap2.h
@@ -16,19 +16,7 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
-#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
-};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+#ifndef _ASM_X86_HWCAP2_H
+#define _ASM_X86_HWCAP2_H
+#define HWCAP2_RING3MWAIT (1 << 0)
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/hyperv.h b/libc/kernel/uapi/asm-x86/asm/hyperv.h
index 3796533..2d4b97a 100644
--- a/libc/kernel/uapi/asm-x86/asm/hyperv.h
+++ b/libc/kernel/uapi/asm-x86/asm/hyperv.h
@@ -41,6 +41,7 @@
#define HV_X64_MSR_VP_INDEX_AVAILABLE (1 << 6)
#define HV_X64_MSR_RESET_AVAILABLE (1 << 7)
#define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8)
+#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
#define HV_X64_CREATE_PARTITIONS (1 << 0)
#define HV_X64_ACCESS_PARTITION_ID (1 << 1)
#define HV_X64_ACCESS_MEMORY_POOL (1 << 2)
@@ -60,12 +61,14 @@
#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE (1 << 4)
#define HV_X64_GUEST_IDLE_STATE_AVAILABLE (1 << 5)
#define HV_X64_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
-#define HV_X64_MWAIT_RECOMMENDED (1 << 0)
+#define HV_X64_AS_SWITCH_RECOMMENDED (1 << 0)
#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED (1 << 1)
#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED (1 << 2)
#define HV_X64_APIC_ACCESS_RECOMMENDED (1 << 3)
#define HV_X64_SYSTEM_RESET_RECOMMENDED (1 << 4)
#define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5)
+#define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9)
+#define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63)
#define HV_X64_MSR_GUEST_OS_ID 0x40000000
#define HV_X64_MSR_HYPERCALL 0x40000001
#define HV_X64_MSR_VP_INDEX 0x40000002
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 75680ee..913d4bc 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -20,6 +20,8 @@
#define _ASM_X86_KVM_H
#include <linux/types.h>
#include <linux/ioctl.h>
+#define KVM_PIO_PAGE_OFFSET 1
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 2
#define DE_VECTOR 0
#define DB_VECTOR 1
#define BP_VECTOR 3
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm_para.h b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
index 19cab4a..78008df 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm_para.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
@@ -47,6 +47,14 @@
__u8 u8_pad[3];
__u32 pad[11];
};
+#define KVM_CLOCK_PAIRING_WALLCLOCK 0
+struct kvm_clock_pairing {
+ __s64 sec;
+ __s64 nsec;
+ __u64 tsc;
+ __u32 flags;
+ __u32 pad[9];
+};
#define KVM_STEAL_ALIGNMENT_BITS 5
#define KVM_STEAL_VALID_BITS ((- 1ULL << (KVM_STEAL_ALIGNMENT_BITS + 1)))
#define KVM_STEAL_RESERVED_MASK (((1 << KVM_STEAL_ALIGNMENT_BITS) - 1) << 1)
diff --git a/libc/kernel/uapi/asm-x86/asm/prctl.h b/libc/kernel/uapi/asm-x86/asm/prctl.h
index bb68f7e..0e6bed9 100644
--- a/libc/kernel/uapi/asm-x86/asm/prctl.h
+++ b/libc/kernel/uapi/asm-x86/asm/prctl.h
@@ -22,6 +22,8 @@
#define ARCH_SET_FS 0x1002
#define ARCH_GET_FS 0x1003
#define ARCH_GET_GS 0x1004
+#define ARCH_GET_CPUID 0x1011
+#define ARCH_SET_CPUID 0x1012
#define ARCH_MAP_VDSO_X32 0x2001
#define ARCH_MAP_VDSO_32 0x2002
#define ARCH_MAP_VDSO_64 0x2003
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_32.h b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
index 184c230..0038efb 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
@@ -397,4 +397,6 @@
#define __NR_pkey_mprotect 380
#define __NR_pkey_alloc 381
#define __NR_pkey_free 382
+#define __NR_statx 383
+#define __NR_arch_prctl 384
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_64.h b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
index c386eaf..3cde166 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_64.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
@@ -350,4 +350,5 @@
#define __NR_pkey_mprotect 329
#define __NR_pkey_alloc 330
#define __NR_pkey_free 331
+#define __NR_statx 332
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
index 2995659..e10cc6b 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
@@ -303,6 +303,7 @@
#define __NR_pkey_mprotect (__X32_SYSCALL_BIT + 329)
#define __NR_pkey_alloc (__X32_SYSCALL_BIT + 330)
#define __NR_pkey_free (__X32_SYSCALL_BIT + 331)
+#define __NR_statx (__X32_SYSCALL_BIT + 332)
#define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
#define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
#define __NR_ioctl (__X32_SYSCALL_BIT + 514)
diff --git a/libc/kernel/uapi/asm-x86/asm/vmx.h b/libc/kernel/uapi/asm-x86/asm/vmx.h
index af2b727..83365f8 100644
--- a/libc/kernel/uapi/asm-x86/asm/vmx.h
+++ b/libc/kernel/uapi/asm-x86/asm/vmx.h
@@ -67,11 +67,15 @@
#define EXIT_REASON_WBINVD 54
#define EXIT_REASON_XSETBV 55
#define EXIT_REASON_APIC_WRITE 56
+#define EXIT_REASON_RDRAND 57
#define EXIT_REASON_INVPCID 58
+#define EXIT_REASON_VMFUNC 59
+#define EXIT_REASON_ENCLS 60
+#define EXIT_REASON_RDSEED 61
#define EXIT_REASON_PML_FULL 62
#define EXIT_REASON_XSAVES 63
#define EXIT_REASON_XRSTORS 64
-#define VMX_EXIT_REASONS { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, { EXIT_REASON_CPUID, "CPUID" }, { EXIT_REASON_HLT, "HLT" }, { EXIT_REASON_INVLPG, "INVLPG" }, { EXIT_REASON_RDPMC, "RDPMC" }, { EXIT_REASON_RDTSC, "RDTSC" }, { EXIT_REASON_VMCALL, "VMCALL" }, { EXIT_REASON_VMCLEAR, "VMCLEAR" }, { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, { EXIT_REASON_VMPTRLD, "VMPTRLD" }, { EXIT_REASON_VMPTRST, "VMPTRST" }, { EXIT_REASON_VMREAD, "VMREAD" }, { EXIT_REASON_VMRESUME, "VMRESUME" }, { EXIT_REASON_VMWRITE, "VMWRITE" }, { EXIT_REASON_VMOFF, "VMOFF" }, { EXIT_REASON_VMON, "VMON" }, { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, { EXIT_REASON_MSR_READ, "MSR_READ" }, { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, { EXIT_REASON_MONITOR_TRAP_FLAG, "MONITOR_TRAP_FLAG" }, { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, { EXIT_REASON_GDTR_IDTR, "GDTR_IDTR" }, { EXIT_REASON_LDTR_TR, "LDTR_TR" }, { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, { EXIT_REASON_INVEPT, "INVEPT" }, { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, { EXIT_REASON_WBINVD, "WBINVD" }, { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, { EXIT_REASON_MSR_LOAD_FAIL, "MSR_LOAD_FAIL" }, { EXIT_REASON_INVD, "INVD" }, { EXIT_REASON_INVVPID, "INVVPID" }, { EXIT_REASON_INVPCID, "INVPCID" }, { EXIT_REASON_XSAVES, "XSAVES" }, { EXIT_REASON_XRSTORS, "XRSTORS" }
+#define VMX_EXIT_REASONS { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, { EXIT_REASON_CPUID, "CPUID" }, { EXIT_REASON_HLT, "HLT" }, { EXIT_REASON_INVD, "INVD" }, { EXIT_REASON_INVLPG, "INVLPG" }, { EXIT_REASON_RDPMC, "RDPMC" }, { EXIT_REASON_RDTSC, "RDTSC" }, { EXIT_REASON_VMCALL, "VMCALL" }, { EXIT_REASON_VMCLEAR, "VMCLEAR" }, { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, { EXIT_REASON_VMPTRLD, "VMPTRLD" }, { EXIT_REASON_VMPTRST, "VMPTRST" }, { EXIT_REASON_VMREAD, "VMREAD" }, { EXIT_REASON_VMRESUME, "VMRESUME" }, { EXIT_REASON_VMWRITE, "VMWRITE" }, { EXIT_REASON_VMOFF, "VMOFF" }, { EXIT_REASON_VMON, "VMON" }, { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, { EXIT_REASON_MSR_READ, "MSR_READ" }, { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, { EXIT_REASON_MSR_LOAD_FAIL, "MSR_LOAD_FAIL" }, { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, { EXIT_REASON_MONITOR_TRAP_FLAG, "MONITOR_TRAP_FLAG" }, { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, { EXIT_REASON_GDTR_IDTR, "GDTR_IDTR" }, { EXIT_REASON_LDTR_TR, "LDTR_TR" }, { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, { EXIT_REASON_INVEPT, "INVEPT" }, { EXIT_REASON_RDTSCP, "RDTSCP" }, { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, { EXIT_REASON_INVVPID, "INVVPID" }, { EXIT_REASON_WBINVD, "WBINVD" }, { EXIT_REASON_XSETBV, "XSETBV" }, { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, { EXIT_REASON_RDRAND, "RDRAND" }, { EXIT_REASON_INVPCID, "INVPCID" }, { EXIT_REASON_VMFUNC, "VMFUNC" }, { EXIT_REASON_ENCLS, "ENCLS" }, { EXIT_REASON_RDSEED, "RDSEED" }, { EXIT_REASON_PML_FULL, "PML_FULL" }, { EXIT_REASON_XSAVES, "XSAVES" }, { EXIT_REASON_XRSTORS, "XRSTORS" }
#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1
#define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2
#define VMX_ABORT_LOAD_HOST_MSR_FAIL 4
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index e1768c6..f5e8b16 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -149,8 +149,10 @@
#define AMDGPU_TILING_MACRO_TILE_ASPECT_MASK 0x3
#define AMDGPU_TILING_NUM_BANKS_SHIFT 21
#define AMDGPU_TILING_NUM_BANKS_MASK 0x3
-#define AMDGPU_TILING_SET(field,value) (((value) & AMDGPU_TILING_ ##field ##_MASK) << AMDGPU_TILING_ ##field ##_SHIFT)
-#define AMDGPU_TILING_GET(value,field) (((value) >> AMDGPU_TILING_ ##field ##_SHIFT) & AMDGPU_TILING_ ##field ##_MASK)
+#define AMDGPU_TILING_SWIZZLE_MODE_SHIFT 0
+#define AMDGPU_TILING_SWIZZLE_MODE_MASK 0x1f
+#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
#define AMDGPU_GEM_METADATA_OP_GET_METADATA 2
struct drm_amdgpu_gem_metadata {
@@ -232,10 +234,19 @@
};
#define AMDGPU_VA_OP_MAP 1
#define AMDGPU_VA_OP_UNMAP 2
+#define AMDGPU_VA_OP_CLEAR 3
+#define AMDGPU_VA_OP_REPLACE 4
#define AMDGPU_VM_DELAY_UPDATE (1 << 0)
#define AMDGPU_VM_PAGE_READABLE (1 << 1)
#define AMDGPU_VM_PAGE_WRITEABLE (1 << 2)
#define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3)
+#define AMDGPU_VM_PAGE_PRT (1 << 4)
+#define AMDGPU_VM_MTYPE_MASK (0xf << 5)
+#define AMDGPU_VM_MTYPE_DEFAULT (0 << 5)
+#define AMDGPU_VM_MTYPE_NC (1 << 5)
+#define AMDGPU_VM_MTYPE_WC (2 << 5)
+#define AMDGPU_VM_MTYPE_CC (3 << 5)
+#define AMDGPU_VM_MTYPE_UC (4 << 5)
struct drm_amdgpu_gem_va {
__u32 handle;
__u32 _pad;
@@ -250,7 +261,8 @@
#define AMDGPU_HW_IP_DMA 2
#define AMDGPU_HW_IP_UVD 3
#define AMDGPU_HW_IP_VCE 4
-#define AMDGPU_HW_IP_NUM 5
+#define AMDGPU_HW_IP_UVD_ENC 5
+#define AMDGPU_HW_IP_NUM 6
#define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
#define AMDGPU_CHUNK_ID_IB 0x01
#define AMDGPU_CHUNK_ID_FENCE 0x02
@@ -276,6 +288,7 @@
};
#define AMDGPU_IB_FLAG_CE (1 << 0)
#define AMDGPU_IB_FLAG_PREAMBLE (1 << 1)
+#define AMDGPU_IB_FLAG_PREEMPT (1 << 2)
struct drm_amdgpu_cs_chunk_ib {
__u32 _pad;
__u32 flags;
@@ -320,6 +333,8 @@
#define AMDGPU_INFO_FW_GFX_MEC 0x08
#define AMDGPU_INFO_FW_SMC 0x0a
#define AMDGPU_INFO_FW_SDMA 0x0b
+#define AMDGPU_INFO_FW_SOS 0x0c
+#define AMDGPU_INFO_FW_ASD 0x0d
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
#define AMDGPU_INFO_VRAM_USAGE 0x10
#define AMDGPU_INFO_GTT_USAGE 0x11
@@ -334,6 +349,15 @@
#define AMDGPU_INFO_VBIOS 0x1B
#define AMDGPU_INFO_VBIOS_SIZE 0x1
#define AMDGPU_INFO_VBIOS_IMAGE 0x2
+#define AMDGPU_INFO_NUM_HANDLES 0x1C
+#define AMDGPU_INFO_SENSOR 0x1D
+#define AMDGPU_INFO_SENSOR_GFX_SCLK 0x1
+#define AMDGPU_INFO_SENSOR_GFX_MCLK 0x2
+#define AMDGPU_INFO_SENSOR_GPU_TEMP 0x3
+#define AMDGPU_INFO_SENSOR_GPU_LOAD 0x4
+#define AMDGPU_INFO_SENSOR_GPU_AVG_POWER 0x5
+#define AMDGPU_INFO_SENSOR_VDDNB 0x6
+#define AMDGPU_INFO_SENSOR_VDDGFX 0x7
#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
#define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
@@ -368,6 +392,9 @@
__u32 type;
__u32 offset;
} vbios_info;
+ struct {
+ __u32 type;
+ } sensor_info;
};
};
struct drm_amdgpu_info_gds {
@@ -436,6 +463,23 @@
__u32 vram_type;
__u32 vram_bit_width;
__u32 vce_harvest_config;
+ __u32 gc_double_offchip_lds_buf;
+ __u64 prim_buf_gpu_addr;
+ __u64 pos_buf_gpu_addr;
+ __u64 cntl_sb_buf_gpu_addr;
+ __u64 param_buf_gpu_addr;
+ __u32 prim_buf_size;
+ __u32 pos_buf_size;
+ __u32 cntl_sb_buf_size;
+ __u32 param_buf_size;
+ __u32 wave_front_size;
+ __u32 num_shader_visible_vgprs;
+ __u32 num_cu_per_sh;
+ __u32 num_tcc_blocks;
+ __u32 gs_vgt_table_depth;
+ __u32 gs_prim_buffer_depth;
+ __u32 max_gs_waves_per_vgt;
+ __u32 _pad1;
};
struct drm_amdgpu_info_hw_ip {
__u32 hw_ip_version_major;
@@ -446,6 +490,10 @@
__u32 available_rings;
__u32 _pad;
};
+struct drm_amdgpu_info_num_handles {
+ __u32 uvd_max_handles;
+ __u32 uvd_used_handles;
+};
#define AMDGPU_VCE_CLOCK_TABLE_ENTRIES 6
struct drm_amdgpu_info_vce_clock_table_entry {
__u32 sclk;
@@ -464,6 +512,7 @@
#define AMDGPU_FAMILY_KV 125
#define AMDGPU_FAMILY_VI 130
#define AMDGPU_FAMILY_CZ 135
+#define AMDGPU_FAMILY_AI 141
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index d28c054..251deeb 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -360,6 +360,7 @@
#define DRM_CAP_CURSOR_HEIGHT 0x9
#define DRM_CAP_ADDFB2_MODIFIERS 0x10
#define DRM_CAP_PAGE_FLIP_TARGET 0x11
+#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12
struct drm_get_cap {
__u64 capability;
__u64 value;
@@ -490,7 +491,7 @@
__u32 tv_sec;
__u32 tv_usec;
__u32 sequence;
- __u32 reserved;
+ __u32 crtc_id;
};
typedef struct drm_clip_rect drm_clip_rect_t;
typedef struct drm_drawable_info drm_drawable_info_t;
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index 0747742..630ad30 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -25,8 +25,11 @@
#define DRM_FORMAT_BIG_ENDIAN (1 << 31)
#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ')
#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
+#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ')
#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8')
#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')
+#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2')
+#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2')
#define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8')
#define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8')
#define DRM_FORMAT_XRGB4444 fourcc_code('X', 'R', '1', '2')
@@ -70,6 +73,14 @@
#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_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')
+#define DRM_FORMAT_BGRX8888_A8 fourcc_code('B', 'X', 'A', '8')
+#define DRM_FORMAT_RGB888_A8 fourcc_code('R', '8', 'A', '8')
+#define DRM_FORMAT_BGR888_A8 fourcc_code('B', '8', 'A', '8')
+#define DRM_FORMAT_RGB565_A8 fourcc_code('R', '5', 'A', '8')
+#define DRM_FORMAT_BGR565_A8 fourcc_code('B', '5', 'A', '8')
#define DRM_FORMAT_NV12 fourcc_code('N', 'V', '1', '2')
#define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1')
#define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6')
@@ -87,16 +98,29 @@
#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4')
#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4')
#define DRM_FORMAT_MOD_NONE 0
+#define DRM_FORMAT_MOD_VENDOR_NONE 0
#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01
#define DRM_FORMAT_MOD_VENDOR_AMD 0x02
#define DRM_FORMAT_MOD_VENDOR_NV 0x03
#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04
#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
+#define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06
#define fourcc_mod_code(vendor,val) ((((__u64) DRM_FORMAT_MOD_VENDOR_ ##vendor) << 56) | (val & 0x00ffffffffffffffULL))
+#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1)
#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2)
#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+#define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1)
+#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2)
+#define DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED fourcc_mod_code(VIVANTE, 3)
+#define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4)
+#define __fourcc_mod_tegra_mode_shift 32
+#define fourcc_mod_tegra_code(val,params) fourcc_mod_code(NV, ((((__u64) val) << __fourcc_mod_tegra_mode_shift) | params))
+#define fourcc_mod_tegra_mod(m) (m & ~((1ULL << __fourcc_mod_tegra_mode_shift) - 1))
+#define fourcc_mod_tegra_param(m) (m & ((1ULL << __fourcc_mod_tegra_mode_shift) - 1))
+#define NV_FORMAT_MOD_TEGRA_TILED fourcc_mod_tegra_code(1, 0)
+#define NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(v) fourcc_mod_tegra_code(2, v)
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index f15f3c6..9e7ee92 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -77,6 +77,8 @@
#define DRM_MODE_DIRTY_OFF 0
#define DRM_MODE_DIRTY_ON 1
#define DRM_MODE_DIRTY_ANNOTATE 2
+#define DRM_MODE_LINK_STATUS_GOOD 0
+#define DRM_MODE_LINK_STATUS_BAD 1
struct drm_mode_modeinfo {
__u32 clock;
__u16 hdisplay;
diff --git a/libc/kernel/uapi/drm/etnaviv_drm.h b/libc/kernel/uapi/drm/etnaviv_drm.h
index 04a1640..6376e25 100644
--- a/libc/kernel/uapi/drm/etnaviv_drm.h
+++ b/libc/kernel/uapi/drm/etnaviv_drm.h
@@ -91,6 +91,10 @@
__u32 handle;
__u64 presumed;
};
+#define ETNA_SUBMIT_NO_IMPLICIT 0x0001
+#define ETNA_SUBMIT_FENCE_FD_IN 0x0002
+#define ETNA_SUBMIT_FENCE_FD_OUT 0x0004
+#define ETNA_SUBMIT_FLAGS (ETNA_SUBMIT_NO_IMPLICIT | ETNA_SUBMIT_FENCE_FD_IN | ETNA_SUBMIT_FENCE_FD_OUT)
#define ETNA_PIPE_3D 0x00
#define ETNA_PIPE_2D 0x01
#define ETNA_PIPE_VG 0x02
@@ -104,6 +108,8 @@
__u64 bos;
__u64 relocs;
__u64 stream;
+ __u32 flags;
+ __s32 fence_fd;
};
#define ETNA_WAIT_NONBLOCK 0x01
struct drm_etnaviv_wait_fence {
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 3279d26..af6f064 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -158,6 +158,7 @@
#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
#define DRM_I915_OVERLAY_ATTRS 0x28
#define DRM_I915_GEM_EXECBUFFER2 0x29
+#define DRM_I915_GEM_EXECBUFFER2_WR DRM_I915_GEM_EXECBUFFER2
#define DRM_I915_GET_SPRITE_COLORKEY 0x2a
#define DRM_I915_SET_SPRITE_COLORKEY 0x2b
#define DRM_I915_GEM_WAIT 0x2c
@@ -170,6 +171,7 @@
#define DRM_I915_GEM_USERPTR 0x33
#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
+#define DRM_I915_PERF_OPEN 0x36
#define DRM_IOCTL_I915_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO(DRM_COMMAND_BASE + DRM_I915_FLUSH)
#define DRM_IOCTL_I915_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_I915_FLIP)
@@ -190,6 +192,7 @@
#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init)
#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer)
#define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER2_WR DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2_WR, struct drm_i915_gem_execbuffer2)
#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
@@ -222,6 +225,7 @@
#define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr)
#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
+#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
typedef struct drm_i915_batchbuffer {
int start;
int used;
@@ -285,6 +289,9 @@
#define I915_PARAM_MIN_EU_IN_POOL 39
#define I915_PARAM_MMAP_GTT_VERSION 40
#define I915_PARAM_HAS_SCHEDULER 41
+#define I915_PARAM_HUC_STATUS 42
+#define I915_PARAM_HAS_EXEC_ASYNC 43
+#define I915_PARAM_HAS_EXEC_FENCE 44
typedef struct drm_i915_getparam {
__s32 param;
int __user * value;
@@ -418,7 +425,8 @@
#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1 << 3)
#define EXEC_OBJECT_PINNED (1 << 4)
#define EXEC_OBJECT_PAD_TO_SIZE (1 << 5)
-#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_PAD_TO_SIZE << 1)
+#define EXEC_OBJECT_ASYNC (1 << 6)
+#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_ASYNC << 1)
__u64 flags;
union {
__u64 rsvd1;
@@ -460,7 +468,9 @@
#define I915_EXEC_BSD_RING1 (1 << I915_EXEC_BSD_SHIFT)
#define I915_EXEC_BSD_RING2 (2 << I915_EXEC_BSD_SHIFT)
#define I915_EXEC_RESOURCE_STREAMER (1 << 15)
-#define __I915_EXEC_UNKNOWN_FLAGS - (I915_EXEC_RESOURCE_STREAMER << 1)
+#define I915_EXEC_FENCE_IN (1 << 16)
+#define I915_EXEC_FENCE_OUT (1 << 17)
+#define __I915_EXEC_UNKNOWN_FLAGS (- (I915_EXEC_FENCE_OUT << 1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2,context) (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
#define i915_execbuffer2_get_context_id(eb2) ((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
@@ -629,8 +639,48 @@
#define I915_CONTEXT_PARAM_NO_ZEROMAP 0x2
#define I915_CONTEXT_PARAM_GTT_SIZE 0x3
#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
+#define I915_CONTEXT_PARAM_BANNABLE 0x5
__u64 value;
};
+enum drm_i915_oa_format {
+ I915_OA_FORMAT_A13 = 1,
+ I915_OA_FORMAT_A29,
+ I915_OA_FORMAT_A13_B8_C8,
+ I915_OA_FORMAT_B4_C8,
+ I915_OA_FORMAT_A45_B8_C8,
+ I915_OA_FORMAT_B4_C8_A16,
+ I915_OA_FORMAT_C4_B8,
+ I915_OA_FORMAT_MAX
+};
+enum drm_i915_perf_property_id {
+ DRM_I915_PERF_PROP_CTX_HANDLE = 1,
+ DRM_I915_PERF_PROP_SAMPLE_OA,
+ DRM_I915_PERF_PROP_OA_METRICS_SET,
+ DRM_I915_PERF_PROP_OA_FORMAT,
+ DRM_I915_PERF_PROP_OA_EXPONENT,
+ DRM_I915_PERF_PROP_MAX
+};
+struct drm_i915_perf_open_param {
+ __u32 flags;
+#define I915_PERF_FLAG_FD_CLOEXEC (1 << 0)
+#define I915_PERF_FLAG_FD_NONBLOCK (1 << 1)
+#define I915_PERF_FLAG_DISABLED (1 << 2)
+ __u32 num_properties;
+ __u64 properties_ptr;
+};
+#define I915_PERF_IOCTL_ENABLE _IO('i', 0x0)
+#define I915_PERF_IOCTL_DISABLE _IO('i', 0x1)
+struct drm_i915_perf_record_header {
+ __u32 type;
+ __u16 pad;
+ __u16 size;
+};
+enum drm_i915_perf_record_type {
+ DRM_I915_PERF_RECORD_SAMPLE = 1,
+ DRM_I915_PERF_RECORD_OA_REPORT_LOST = 2,
+ DRM_I915_PERF_RECORD_OA_BUFFER_LOST = 3,
+ DRM_I915_PERF_RECORD_MAX
+};
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index a8e4943..83ad769 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -37,6 +37,7 @@
#define MSM_PARAM_CHIP_ID 0x03
#define MSM_PARAM_MAX_FREQ 0x04
#define MSM_PARAM_TIMESTAMP 0x05
+#define MSM_PARAM_GMEM_BASE 0x06
struct drm_msm_param {
__u32 pipe;
__u32 param;
diff --git a/libc/kernel/uapi/drm/omap_drm.h b/libc/kernel/uapi/drm/omap_drm.h
index 2da6420..54b539a 100644
--- a/libc/kernel/uapi/drm/omap_drm.h
+++ b/libc/kernel/uapi/drm/omap_drm.h
@@ -23,8 +23,8 @@
#endif
#define OMAP_PARAM_CHIPSET_ID 1
struct drm_omap_param {
- uint64_t param;
- uint64_t value;
+ __u64 param;
+ __u64 value;
};
#define OMAP_BO_SCANOUT 0x00000001
#define OMAP_BO_CACHE_MASK 0x00000006
@@ -37,38 +37,38 @@
#define OMAP_BO_TILED_32 0x00000300
#define OMAP_BO_TILED (OMAP_BO_TILED_8 | OMAP_BO_TILED_16 | OMAP_BO_TILED_32)
union omap_gem_size {
- uint32_t bytes;
+ __u32 bytes;
struct {
- uint16_t width;
- uint16_t height;
+ __u16 width;
+ __u16 height;
} tiled;
};
struct drm_omap_gem_new {
union omap_gem_size size;
- uint32_t flags;
- uint32_t handle;
- uint32_t __pad;
+ __u32 flags;
+ __u32 handle;
+ __u32 __pad;
};
enum omap_gem_op {
OMAP_GEM_READ = 0x01,
OMAP_GEM_WRITE = 0x02,
};
struct drm_omap_gem_cpu_prep {
- uint32_t handle;
- uint32_t op;
+ __u32 handle;
+ __u32 op;
};
struct drm_omap_gem_cpu_fini {
- uint32_t handle;
- uint32_t op;
- uint32_t nregions;
- uint32_t __pad;
+ __u32 handle;
+ __u32 op;
+ __u32 nregions;
+ __u32 __pad;
};
struct drm_omap_gem_info {
- uint32_t handle;
- uint32_t pad;
- uint64_t offset;
- uint32_t size;
- uint32_t __pad;
+ __u32 handle;
+ __u32 pad;
+ __u64 offset;
+ __u32 size;
+ __u32 __pad;
};
#define DRM_OMAP_GET_PARAM 0x00
#define DRM_OMAP_SET_PARAM 0x01
diff --git a/libc/kernel/uapi/drm/vmwgfx_drm.h b/libc/kernel/uapi/drm/vmwgfx_drm.h
index a9e6952..2b7e0fe 100644
--- a/libc/kernel/uapi/drm/vmwgfx_drm.h
+++ b/libc/kernel/uapi/drm/vmwgfx_drm.h
@@ -26,6 +26,7 @@
#define DRM_VMW_GET_PARAM 0
#define DRM_VMW_ALLOC_DMABUF 1
#define DRM_VMW_UNREF_DMABUF 2
+#define DRM_VMW_HANDLE_CLOSE 2
#define DRM_VMW_CURSOR_BYPASS 3
#define DRM_VMW_CONTROL_STREAM 4
#define DRM_VMW_CLAIM_STREAM 5
@@ -314,6 +315,10 @@
enum drm_vmw_extended_context req;
struct drm_vmw_context_arg rep;
};
+struct drm_vmw_handle_close_arg {
+ __u32 handle;
+ __u32 pad64;
+};
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/linux/a.out.h b/libc/kernel/uapi/linux/a.out.h
index a3809b8..8f58c99 100644
--- a/libc/kernel/uapi/linux/a.out.h
+++ b/libc/kernel/uapi/linux/a.out.h
@@ -87,20 +87,6 @@
#ifndef N_TXTADDR
#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
#endif
-#if defined(vax) || defined(hp300) || defined(pyr)
-#define SEGMENT_SIZE page_size
-#endif
-#ifdef sony
-#define SEGMENT_SIZE 0x2000
-#endif
-#ifdef is68k
-#define SEGMENT_SIZE 0x20000
-#endif
-#if defined(m68k) && defined(PORTAR)
-#define PAGE_SIZE 0x400
-#define SEGMENT_SIZE PAGE_SIZE
-#endif
-#ifdef linux
#include <unistd.h>
#if defined(__i386__) || defined(__mc68000__)
#define SEGMENT_SIZE 1024
@@ -109,7 +95,6 @@
#define SEGMENT_SIZE getpagesize()
#endif
#endif
-#endif
#define _N_SEGMENT_ROUND(x) ALIGN(x, SEGMENT_SIZE)
#define _N_TXTENDADDR(x) (N_TXTADDR(x) + (x).a_text)
#ifndef N_DATADDR
@@ -171,13 +156,7 @@
unsigned int r_pcrel : 1;
unsigned int r_length : 2;
unsigned int r_extern : 1;
-#ifdef NS32K
- unsigned r_bsr : 1;
- unsigned r_disp : 1;
- unsigned r_pad : 2;
-#else
unsigned int r_pad : 4;
-#endif
};
#endif
#endif
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 5a7929f..717826d 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -28,6 +28,8 @@
BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),
BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),
BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),
+ BINDER_TYPE_FDA = B_PACK_CHARS('f', 'd', 'a', B_TYPE_LARGE),
+ BINDER_TYPE_PTR = B_PACK_CHARS('p', 't', '*', B_TYPE_LARGE),
};
enum {
FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
@@ -40,8 +42,11 @@
typedef __u64 binder_size_t;
typedef __u64 binder_uintptr_t;
#endif
-struct flat_binder_object {
+struct binder_object_header {
__u32 type;
+};
+struct flat_binder_object {
+ struct binder_object_header hdr;
__u32 flags;
union {
binder_uintptr_t binder;
@@ -49,6 +54,32 @@
};
binder_uintptr_t cookie;
};
+struct binder_fd_object {
+ struct binder_object_header hdr;
+ __u32 pad_flags;
+ union {
+ binder_uintptr_t pad_binder;
+ __u32 fd;
+ };
+ binder_uintptr_t cookie;
+};
+struct binder_buffer_object {
+ struct binder_object_header hdr;
+ __u32 flags;
+ binder_uintptr_t buffer;
+ binder_size_t length;
+ binder_size_t parent;
+ binder_size_t parent_offset;
+};
+enum {
+ BINDER_BUFFER_FLAG_HAS_PARENT = 0x01,
+};
+struct __kernel_binder_fd_array_object {
+ struct binder_object_header hdr;
+ binder_size_t num_fds;
+ binder_size_t parent;
+ binder_size_t parent_offset;
+};
struct binder_write_read {
binder_size_t write_size;
binder_size_t write_consumed;
@@ -98,6 +129,10 @@
__u8 buf[8];
} data;
};
+struct binder_transaction_data_sg {
+ struct binder_transaction_data transaction_data;
+ binder_size_t buffers_size;
+};
struct binder_ptr_cookie {
binder_uintptr_t ptr;
binder_uintptr_t cookie;
@@ -153,5 +188,7 @@
BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_handle_cookie),
BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_handle_cookie),
BC_DEAD_BINDER_DONE = _IOW('c', 16, binder_uintptr_t),
+ BC_TRANSACTION_SG = _IOW('c', 17, struct binder_transaction_data_sg),
+ BC_REPLY_SG = _IOW('c', 18, struct binder_transaction_data_sg),
};
#endif
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/aspeed-lpc-ctrl.h
similarity index 65%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/aspeed-lpc-ctrl.h
index 3064508..fcde081 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/aspeed-lpc-ctrl.h
@@ -16,19 +16,21 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
+#ifndef _UAPI_LINUX_ASPEED_LPC_CTRL_H
+#define _UAPI_LINUX_ASPEED_LPC_CTRL_H
#include <linux/ioctl.h>
#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
+#define ASPEED_LPC_CTRL_WINDOW_FLASH 1
+#define ASPEED_LPC_CTRL_WINDOW_MEMORY 2
+struct aspeed_lpc_ctrl_mapping {
+ __u8 window_type;
+ __u8 window_id;
+ __u16 flags;
+ __u32 addr;
+ __u32 offset;
+ __u32 size;
};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+#define __ASPEED_LPC_CTRL_IOCTL_MAGIC 0xb2
+#define ASPEED_LPC_CTRL_IOCTL_GET_SIZE _IOWR(__ASPEED_LPC_CTRL_IOCTL_MAGIC, 0x00, struct aspeed_lpc_ctrl_mapping)
+#define ASPEED_LPC_CTRL_IOCTL_MAP _IOW(__ASPEED_LPC_CTRL_IOCTL_MAGIC, 0x01, struct aspeed_lpc_ctrl_mapping)
#endif
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index 3eeda4c..3edd1d4 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -77,6 +77,7 @@
#define AUDIT_PROCTITLE 1327
#define AUDIT_FEATURE_CHANGE 1328
#define AUDIT_REPLACE 1329
+#define AUDIT_KERN_MODULE 1330
#define AUDIT_AVC 1400
#define AUDIT_SELINUX_ERR 1401
#define AUDIT_AVC_PATH 1402
@@ -234,12 +235,14 @@
#define AUDIT_STATUS_RATE_LIMIT 0x0008
#define AUDIT_STATUS_BACKLOG_LIMIT 0x0010
#define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
+#define AUDIT_STATUS_LOST 0x0040
#define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT 0x00000001
#define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002
#define AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH 0x00000004
#define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008
#define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010
-#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER)
+#define AUDIT_FEATURE_BITMAP_LOST_RESET 0x00000020
+#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | AUDIT_FEATURE_BITMAP_LOST_RESET)
#define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL
#define AUDIT_VERSION_BACKLOG_LIMIT AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT
#define AUDIT_VERSION_BACKLOG_WAIT_TIME AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME
diff --git a/libc/kernel/uapi/linux/auto_dev-ioctl.h b/libc/kernel/uapi/linux/auto_dev-ioctl.h
index 7068876..be00b9e 100644
--- a/libc/kernel/uapi/linux/auto_dev-ioctl.h
+++ b/libc/kernel/uapi/linux/auto_dev-ioctl.h
@@ -103,7 +103,6 @@
AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD,
AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD,
};
-#define AUTOFS_IOCTL 0x93
#define AUTOFS_DEV_IOCTL_VERSION _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl)
#define AUTOFS_DEV_IOCTL_PROTOVER _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl)
#define AUTOFS_DEV_IOCTL_PROTOSUBVER _IOWR(AUTOFS_IOCTL, AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl)
diff --git a/libc/kernel/uapi/linux/auto_fs.h b/libc/kernel/uapi/linux/auto_fs.h
index 68041c5..93a3724 100644
--- a/libc/kernel/uapi/linux/auto_fs.h
+++ b/libc/kernel/uapi/linux/auto_fs.h
@@ -46,11 +46,20 @@
int len;
char name[NAME_MAX + 1];
};
-#define AUTOFS_IOC_READY _IO(0x93, 0x60)
-#define AUTOFS_IOC_FAIL _IO(0x93, 0x61)
-#define AUTOFS_IOC_CATATONIC _IO(0x93, 0x62)
-#define AUTOFS_IOC_PROTOVER _IOR(0x93, 0x63, int)
-#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93, 0x64, compat_ulong_t)
-#define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93, 0x64, unsigned long)
-#define AUTOFS_IOC_EXPIRE _IOR(0x93, 0x65, struct autofs_packet_expire)
+#define AUTOFS_IOCTL 0x93
+enum {
+ AUTOFS_IOC_READY_CMD = 0x60,
+ AUTOFS_IOC_FAIL_CMD,
+ AUTOFS_IOC_CATATONIC_CMD,
+ AUTOFS_IOC_PROTOVER_CMD,
+ AUTOFS_IOC_SETTIMEOUT_CMD,
+ AUTOFS_IOC_EXPIRE_CMD,
+};
+#define AUTOFS_IOC_READY _IO(AUTOFS_IOCTL, AUTOFS_IOC_READY_CMD)
+#define AUTOFS_IOC_FAIL _IO(AUTOFS_IOCTL, AUTOFS_IOC_FAIL_CMD)
+#define AUTOFS_IOC_CATATONIC _IO(AUTOFS_IOCTL, AUTOFS_IOC_CATATONIC_CMD)
+#define AUTOFS_IOC_PROTOVER _IOR(AUTOFS_IOCTL, AUTOFS_IOC_PROTOVER_CMD, int)
+#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(AUTOFS_IOCTL, AUTOFS_IOC_SETTIMEOUT_CMD, compat_ulong_t)
+#define AUTOFS_IOC_SETTIMEOUT _IOWR(AUTOFS_IOCTL, AUTOFS_IOC_SETTIMEOUT_CMD, unsigned long)
+#define AUTOFS_IOC_EXPIRE _IOR(AUTOFS_IOCTL, AUTOFS_IOC_EXPIRE_CMD, struct autofs_packet_expire)
#endif
diff --git a/libc/kernel/uapi/linux/auto_fs4.h b/libc/kernel/uapi/linux/auto_fs4.h
index a8d9e42..d09b39b 100644
--- a/libc/kernel/uapi/linux/auto_fs4.h
+++ b/libc/kernel/uapi/linux/auto_fs4.h
@@ -79,9 +79,14 @@
autofs_packet_missing_direct_t missing_direct;
autofs_packet_expire_direct_t expire_direct;
};
-#define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93, 0x66, int)
+enum {
+ AUTOFS_IOC_EXPIRE_MULTI_CMD = 0x66,
+ AUTOFS_IOC_PROTOSUBVER_CMD,
+ AUTOFS_IOC_ASKUMOUNT_CMD = 0x70,
+};
+#define AUTOFS_IOC_EXPIRE_MULTI _IOW(AUTOFS_IOCTL, AUTOFS_IOC_EXPIRE_MULTI_CMD, int)
#define AUTOFS_IOC_EXPIRE_INDIRECT AUTOFS_IOC_EXPIRE_MULTI
#define AUTOFS_IOC_EXPIRE_DIRECT AUTOFS_IOC_EXPIRE_MULTI
-#define AUTOFS_IOC_PROTOSUBVER _IOR(0x93, 0x67, int)
-#define AUTOFS_IOC_ASKUMOUNT _IOR(0x93, 0x70, int)
+#define AUTOFS_IOC_PROTOSUBVER _IOR(AUTOFS_IOCTL, AUTOFS_IOC_PROTOSUBVER_CMD, int)
+#define AUTOFS_IOC_ASKUMOUNT _IOR(AUTOFS_IOCTL, AUTOFS_IOC_ASKUMOUNT_CMD, int)
#endif
diff --git a/libc/kernel/uapi/linux/bcache.h b/libc/kernel/uapi/linux/bcache.h
index c3b3c8a..0933d51 100644
--- a/libc/kernel/uapi/linux/bcache.h
+++ b/libc/kernel/uapi/linux/bcache.h
@@ -18,7 +18,7 @@
****************************************************************************/
#ifndef _LINUX_BCACHE_H
#define _LINUX_BCACHE_H
-#include <asm/types.h>
+#include <linux/types.h>
#define BITMASK(name,type,field,offset,size) static inline __u64 name(const type * k) \
{ return(k->field >> offset) & ~(~0ULL << size); } static inline void SET_ ##name(type * k, __u64 v) \
{ k->field &= ~(~(~0ULL << size) << offset); k->field |= (v & ~(~0ULL << size)) << offset; \
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index b1a6a92..08c1aba 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -57,6 +57,10 @@
__s16 off;
__s32 imm;
};
+struct bpf_lpm_trie_key {
+ __u32 prefixlen;
+ __u8 data[0];
+};
enum bpf_cmd {
BPF_MAP_CREATE,
BPF_MAP_LOOKUP_ELEM,
@@ -68,6 +72,7 @@
BPF_OBJ_GET,
BPF_PROG_ATTACH,
BPF_PROG_DETACH,
+ BPF_PROG_TEST_RUN,
};
enum bpf_map_type {
BPF_MAP_TYPE_UNSPEC,
@@ -81,6 +86,9 @@
BPF_MAP_TYPE_CGROUP_ARRAY,
BPF_MAP_TYPE_LRU_HASH,
BPF_MAP_TYPE_LRU_PERCPU_HASH,
+ BPF_MAP_TYPE_LPM_TRIE,
+ BPF_MAP_TYPE_ARRAY_OF_MAPS,
+ BPF_MAP_TYPE_HASH_OF_MAPS,
};
enum bpf_prog_type {
BPF_PROG_TYPE_UNSPEC,
@@ -105,6 +113,7 @@
};
#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
#define BPF_F_ALLOW_OVERRIDE (1U << 0)
+#define BPF_F_STRICT_ALIGNMENT (1U << 0)
#define BPF_PSEUDO_MAP_FD 1
#define BPF_ANY 0
#define BPF_NOEXIST 1
@@ -118,6 +127,7 @@
__u32 value_size;
__u32 max_entries;
__u32 map_flags;
+ __u32 inner_map_fd;
};
struct {
__u32 map_fd;
@@ -137,6 +147,7 @@
__u32 log_size;
__aligned_u64 log_buf;
__u32 kern_version;
+ __u32 prog_flags;
};
struct {
__aligned_u64 pathname;
@@ -148,8 +159,18 @@
__u32 attach_type;
__u32 attach_flags;
};
+ struct {
+ __u32 prog_fd;
+ __u32 retval;
+ __u32 data_size_in;
+ __u32 data_size_out;
+ __aligned_u64 data_in;
+ __aligned_u64 data_out;
+ __u32 repeat;
+ __u32 duration;
+ } test;
} __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),
+#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),
#define __BPF_ENUM_FN(x) BPF_FUNC_ ##x
enum bpf_func_id {
__BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
@@ -160,6 +181,7 @@
#define BPF_F_HDR_FIELD_MASK 0xfULL
#define BPF_F_PSEUDO_HDR (1ULL << 4)
#define BPF_F_MARK_MANGLED_0 (1ULL << 5)
+#define BPF_F_MARK_ENFORCE (1ULL << 6)
#define BPF_F_INGRESS (1ULL << 0)
#define BPF_F_TUNINFO_IPV6 (1ULL << 0)
#define BPF_F_SKIP_FIELD_MASK 0xffULL
@@ -189,6 +211,7 @@
__u32 tc_classid;
__u32 data;
__u32 data_end;
+ __u32 napi_id;
};
struct bpf_tunnel_key {
__u32 tunnel_id;
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 8a9dcdc..56e33ae 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -183,10 +183,10 @@
struct btrfs_balance_args {
__u64 profiles;
union {
- __le64 usage;
+ __u64 usage;
struct {
- __le32 usage_min;
- __le32 usage_max;
+ __u32 usage_min;
+ __u32 usage_max;
};
};
__u64 devid;
@@ -203,8 +203,8 @@
__u32 limit_max;
};
};
- __le32 stripes_min;
- __le32 stripes_max;
+ __u32 stripes_min;
+ __u32 stripes_max;
__u64 unused[6];
} __attribute__((__packed__));
struct btrfs_balance_progress {
diff --git a/libc/kernel/uapi/linux/btrfs_tree.h b/libc/kernel/uapi/linux/btrfs_tree.h
index 677a580..c75732e 100644
--- a/libc/kernel/uapi/linux/btrfs_tree.h
+++ b/libc/kernel/uapi/linux/btrfs_tree.h
@@ -18,6 +18,8 @@
****************************************************************************/
#ifndef _BTRFS_CTREE_H_
#define _BTRFS_CTREE_H_
+#include <linux/btrfs.h>
+#include <linux/types.h>
#define BTRFS_ROOT_TREE_OBJECTID 1ULL
#define BTRFS_EXTENT_TREE_OBJECTID 2ULL
#define BTRFS_CHUNK_TREE_OBJECTID 3ULL
diff --git a/libc/kernel/uapi/linux/can/netlink.h b/libc/kernel/uapi/linux/can/netlink.h
index e583976..7df626d 100644
--- a/libc/kernel/uapi/linux/can/netlink.h
+++ b/libc/kernel/uapi/linux/can/netlink.h
@@ -88,7 +88,12 @@
IFLA_CAN_BERR_COUNTER,
IFLA_CAN_DATA_BITTIMING,
IFLA_CAN_DATA_BITTIMING_CONST,
+ IFLA_CAN_TERMINATION,
+ IFLA_CAN_TERMINATION_CONST,
+ IFLA_CAN_BITRATE_CONST,
+ IFLA_CAN_DATA_BITRATE_CONST,
__IFLA_CAN_MAX
};
#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1)
+#define CAN_TERMINATION_DISABLED 0
#endif
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/can/vxcan.h
similarity index 67%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/can/vxcan.h
index 3064508..950b645 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/can/vxcan.h
@@ -16,19 +16,12 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
-#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
+#ifndef _UAPI_CAN_VXCAN_H
+#define _UAPI_CAN_VXCAN_H
+enum {
+ VXCAN_INFO_UNSPEC,
+ VXCAN_INFO_PEER,
+ __VXCAN_INFO_MAX
+#define VXCAN_INFO_MAX (__VXCAN_INFO_MAX - 1)
};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
#endif
diff --git a/libc/kernel/uapi/linux/cryptouser.h b/libc/kernel/uapi/linux/cryptouser.h
index c2dbe76..15c46d8 100644
--- a/libc/kernel/uapi/linux/cryptouser.h
+++ b/libc/kernel/uapi/linux/cryptouser.h
@@ -16,6 +16,7 @@
***
****************************************************************************
****************************************************************************/
+#include <linux/types.h>
enum {
CRYPTO_MSG_BASE = 0x10,
CRYPTO_MSG_NEWALG = 0x10,
@@ -27,7 +28,7 @@
};
#define CRYPTO_MSG_MAX (__CRYPTO_MSG_MAX - 1)
#define CRYPTO_NR_MSGTYPES (CRYPTO_MSG_MAX + 1 - CRYPTO_MSG_BASE)
-#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
+#define CRYPTO_MAX_NAME 64
enum crypto_attr_type_t {
CRYPTOCFGA_UNSPEC,
CRYPTOCFGA_PRIORITY_VAL,
@@ -45,9 +46,9 @@
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
};
struct crypto_user_alg {
- char cru_name[CRYPTO_MAX_ALG_NAME];
- char cru_driver_name[CRYPTO_MAX_ALG_NAME];
- char cru_module_name[CRYPTO_MAX_ALG_NAME];
+ char cru_name[CRYPTO_MAX_NAME];
+ char cru_driver_name[CRYPTO_MAX_NAME];
+ char cru_module_name[CRYPTO_MAX_NAME];
__u32 cru_type;
__u32 cru_mask;
__u32 cru_refcnt;
@@ -62,7 +63,7 @@
unsigned int digestsize;
};
struct crypto_report_cipher {
- char type[CRYPTO_MAX_ALG_NAME];
+ char type[CRYPTO_MAX_NAME];
unsigned int blocksize;
unsigned int min_keysize;
unsigned int max_keysize;
diff --git a/libc/kernel/uapi/linux/devlink.h b/libc/kernel/uapi/linux/devlink.h
index c51bf77..01f6e74 100644
--- a/libc/kernel/uapi/linux/devlink.h
+++ b/libc/kernel/uapi/linux/devlink.h
@@ -51,8 +51,14 @@
DEVLINK_CMD_SB_TC_POOL_BIND_DEL,
DEVLINK_CMD_SB_OCC_SNAPSHOT,
DEVLINK_CMD_SB_OCC_MAX_CLEAR,
- DEVLINK_CMD_ESWITCH_MODE_GET,
- DEVLINK_CMD_ESWITCH_MODE_SET,
+ DEVLINK_CMD_ESWITCH_GET,
+#define DEVLINK_CMD_ESWITCH_MODE_GET DEVLINK_CMD_ESWITCH_GET
+ DEVLINK_CMD_ESWITCH_SET,
+#define DEVLINK_CMD_ESWITCH_MODE_SET DEVLINK_CMD_ESWITCH_SET
+ DEVLINK_CMD_DPIPE_TABLE_GET,
+ DEVLINK_CMD_DPIPE_ENTRIES_GET,
+ DEVLINK_CMD_DPIPE_HEADERS_GET,
+ DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
__DEVLINK_CMD_MAX,
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
};
@@ -81,6 +87,10 @@
DEVLINK_ESWITCH_INLINE_MODE_NETWORK,
DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT,
};
+enum devlink_eswitch_encap_mode {
+ DEVLINK_ESWITCH_ENCAP_MODE_NONE,
+ DEVLINK_ESWITCH_ENCAP_MODE_BASIC,
+};
enum devlink_attr {
DEVLINK_ATTR_UNSPEC,
DEVLINK_ATTR_BUS_NAME,
@@ -109,7 +119,53 @@
DEVLINK_ATTR_SB_OCC_MAX,
DEVLINK_ATTR_ESWITCH_MODE,
DEVLINK_ATTR_ESWITCH_INLINE_MODE,
+ DEVLINK_ATTR_DPIPE_TABLES,
+ DEVLINK_ATTR_DPIPE_TABLE,
+ DEVLINK_ATTR_DPIPE_TABLE_NAME,
+ DEVLINK_ATTR_DPIPE_TABLE_SIZE,
+ DEVLINK_ATTR_DPIPE_TABLE_MATCHES,
+ DEVLINK_ATTR_DPIPE_TABLE_ACTIONS,
+ DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
+ DEVLINK_ATTR_DPIPE_ENTRIES,
+ DEVLINK_ATTR_DPIPE_ENTRY,
+ DEVLINK_ATTR_DPIPE_ENTRY_INDEX,
+ DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES,
+ DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES,
+ DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
+ DEVLINK_ATTR_DPIPE_MATCH,
+ DEVLINK_ATTR_DPIPE_MATCH_VALUE,
+ DEVLINK_ATTR_DPIPE_MATCH_TYPE,
+ DEVLINK_ATTR_DPIPE_ACTION,
+ DEVLINK_ATTR_DPIPE_ACTION_VALUE,
+ DEVLINK_ATTR_DPIPE_ACTION_TYPE,
+ DEVLINK_ATTR_DPIPE_VALUE,
+ DEVLINK_ATTR_DPIPE_VALUE_MASK,
+ DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
+ DEVLINK_ATTR_DPIPE_HEADERS,
+ DEVLINK_ATTR_DPIPE_HEADER,
+ DEVLINK_ATTR_DPIPE_HEADER_NAME,
+ DEVLINK_ATTR_DPIPE_HEADER_ID,
+ DEVLINK_ATTR_DPIPE_HEADER_FIELDS,
+ DEVLINK_ATTR_DPIPE_HEADER_GLOBAL,
+ DEVLINK_ATTR_DPIPE_HEADER_INDEX,
+ DEVLINK_ATTR_DPIPE_FIELD,
+ DEVLINK_ATTR_DPIPE_FIELD_NAME,
+ DEVLINK_ATTR_DPIPE_FIELD_ID,
+ DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH,
+ DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE,
+ DEVLINK_ATTR_PAD,
+ DEVLINK_ATTR_ESWITCH_ENCAP_MODE,
__DEVLINK_ATTR_MAX,
DEVLINK_ATTR_MAX = __DEVLINK_ATTR_MAX - 1
};
+enum devlink_dpipe_field_mapping_type {
+ DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE,
+ DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX,
+};
+enum devlink_dpipe_match_type {
+ DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT,
+};
+enum devlink_dpipe_action_type {
+ DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY,
+};
#endif
diff --git a/libc/kernel/uapi/linux/elf-em.h b/libc/kernel/uapi/linux/elf-em.h
index d018ef8..b7c89da 100644
--- a/libc/kernel/uapi/linux/elf-em.h
+++ b/libc/kernel/uapi/linux/elf-em.h
@@ -54,7 +54,6 @@
#define EM_TILEGX 191
#define EM_BPF 247
#define EM_FRV 0x5441
-#define EM_AVR32 0x18ad
#define EM_ALPHA 0x9026
#define EM_CYGNUS_M32R 0x9041
#define EM_S390_OLD 0xA390
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index e8f8bb4..8aa1011 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -345,6 +345,8 @@
#define NT_S390_TDB 0x308
#define NT_S390_VXRS_LOW 0x309
#define NT_S390_VXRS_HIGH 0x30a
+#define NT_S390_GS_CB 0x30b
+#define NT_S390_GS_BC 0x30c
#define NT_ARM_VFP 0x400
#define NT_ARM_TLS 0x401
#define NT_ARM_HW_BREAK 0x402
@@ -353,6 +355,7 @@
#define NT_METAG_CBUF 0x500
#define NT_METAG_RPIPE 0x501
#define NT_METAG_TLS 0x502
+#define NT_ARC_V2 0x600
typedef struct elf32_note {
Elf32_Word n_namesz;
Elf32_Word n_descsz;
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index 2bd4e6c..56df94b 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -619,6 +619,7 @@
#define SPEED_2500 2500
#define SPEED_5000 5000
#define SPEED_10000 10000
+#define SPEED_14000 14000
#define SPEED_20000 20000
#define SPEED_25000 25000
#define SPEED_40000 40000
diff --git a/libc/kernel/uapi/linux/eventpoll.h b/libc/kernel/uapi/linux/eventpoll.h
index ff15c61..d0a5f6e 100644
--- a/libc/kernel/uapi/linux/eventpoll.h
+++ b/libc/kernel/uapi/linux/eventpoll.h
@@ -24,10 +24,21 @@
#define EPOLL_CTL_ADD 1
#define EPOLL_CTL_DEL 2
#define EPOLL_CTL_MOD 3
-#define EPOLLEXCLUSIVE (1 << 28)
-#define EPOLLWAKEUP (1 << 29)
-#define EPOLLONESHOT (1 << 30)
-#define EPOLLET (1 << 31)
+#define EPOLLIN 0x00000001
+#define EPOLLPRI 0x00000002
+#define EPOLLOUT 0x00000004
+#define EPOLLERR 0x00000008
+#define EPOLLHUP 0x00000010
+#define EPOLLRDNORM 0x00000040
+#define EPOLLRDBAND 0x00000080
+#define EPOLLWRNORM 0x00000100
+#define EPOLLWRBAND 0x00000200
+#define EPOLLMSG 0x00000400
+#define EPOLLRDHUP 0x00002000
+#define EPOLLEXCLUSIVE (1U << 28)
+#define EPOLLWAKEUP (1U << 29)
+#define EPOLLONESHOT (1U << 30)
+#define EPOLLET (1U << 31)
#ifdef __x86_64__
#define EPOLL_PACKED __attribute__((packed))
#else
diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h
index 9536d66..c4a8314 100644
--- a/libc/kernel/uapi/linux/fcntl.h
+++ b/libc/kernel/uapi/linux/fcntl.h
@@ -45,4 +45,8 @@
#define AT_SYMLINK_FOLLOW 0x400
#define AT_NO_AUTOMOUNT 0x800
#define AT_EMPTY_PATH 0x1000
+#define AT_STATX_SYNC_TYPE 0x6000
+#define AT_STATX_SYNC_AS_STAT 0x0000
+#define AT_STATX_FORCE_SYNC 0x2000
+#define AT_STATX_DONT_SYNC 0x4000
#endif
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index d27c9e8..75c17a4 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -99,6 +99,7 @@
#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)
@@ -198,10 +199,18 @@
__u8 filenames_encryption_mode;
__u8 flags;
__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
-} __packed;
+};
#define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy)
#define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16])
#define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy)
+#define FS_KEY_DESC_PREFIX "fscrypt:"
+#define FS_KEY_DESC_PREFIX_SIZE 8
+#define FS_MAX_KEY_SIZE 64
+struct fscrypt_key {
+ __u32 mode;
+ __u8 raw[FS_MAX_KEY_SIZE];
+ __u32 size;
+};
#define FS_SECRM_FL 0x00000001
#define FS_UNRM_FL 0x00000002
#define FS_COMPR_FL 0x00000004
diff --git a/libc/kernel/uapi/linux/fsmap.h b/libc/kernel/uapi/linux/fsmap.h
new file mode 100644
index 0000000..fcfea79
--- /dev/null
+++ b/libc/kernel/uapi/linux/fsmap.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 _LINUX_FSMAP_H
+#define _LINUX_FSMAP_H
+#include <linux/types.h>
+struct fsmap {
+ __u32 fmr_device;
+ __u32 fmr_flags;
+ __u64 fmr_physical;
+ __u64 fmr_owner;
+ __u64 fmr_offset;
+ __u64 fmr_length;
+ __u64 fmr_reserved[3];
+};
+struct fsmap_head {
+ __u32 fmh_iflags;
+ __u32 fmh_oflags;
+ __u32 fmh_count;
+ __u32 fmh_entries;
+ __u64 fmh_reserved[6];
+ struct fsmap fmh_keys[2];
+ struct fsmap fmh_recs[];
+};
+#define FMH_IF_VALID 0
+#define FMH_OF_DEV_T 0x1
+#define FMR_OF_PREALLOC 0x1
+#define FMR_OF_ATTR_FORK 0x2
+#define FMR_OF_EXTENT_MAP 0x4
+#define FMR_OF_SHARED 0x8
+#define FMR_OF_SPECIAL_OWNER 0x10
+#define FMR_OF_LAST 0x20
+#define FMR_OWNER(type,code) (((__u64) type << 32) | ((__u64) code & 0xFFFFFFFFULL))
+#define FMR_OWNER_TYPE(owner) ((__u32) ((__u64) owner >> 32))
+#define FMR_OWNER_CODE(owner) ((__u32) (((__u64) owner & 0xFFFFFFFFULL)))
+#define FMR_OWN_FREE FMR_OWNER(0, 1)
+#define FMR_OWN_UNKNOWN FMR_OWNER(0, 2)
+#define FMR_OWN_METADATA FMR_OWNER(0, 3)
+#define FS_IOC_GETFSMAP _IOWR('X', 59, struct fsmap_head)
+#endif
diff --git a/libc/kernel/uapi/linux/gtp.h b/libc/kernel/uapi/linux/gtp.h
index 780f500..bd2fbcb 100644
--- a/libc/kernel/uapi/linux/gtp.h
+++ b/libc/kernel/uapi/linux/gtp.h
@@ -33,7 +33,8 @@
GTPA_LINK,
GTPA_VERSION,
GTPA_TID,
- GTPA_SGSN_ADDRESS,
+ GTPA_PEER_ADDRESS,
+#define GTPA_SGSN_ADDRESS GTPA_PEER_ADDRESS
GTPA_MS_ADDRESS,
GTPA_FLOW,
GTPA_NET_NS_FD,
diff --git a/libc/kernel/uapi/linux/if.h b/libc/kernel/uapi/linux/if.h
index 15207e2..d815ef8 100644
--- a/libc/kernel/uapi/linux/if.h
+++ b/libc/kernel/uapi/linux/if.h
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/compiler.h>
+#include <sys/socket.h>
#if __UAPI_DEF_IF_IFNAMSIZ
#define IFNAMSIZ 16
#endif
diff --git a/libc/kernel/uapi/linux/if_arp.h b/libc/kernel/uapi/linux/if_arp.h
index be3499d..9f056fb 100644
--- a/libc/kernel/uapi/linux/if_arp.h
+++ b/libc/kernel/uapi/linux/if_arp.h
@@ -82,6 +82,7 @@
#define ARPHRD_IP6GRE 823
#define ARPHRD_NETLINK 824
#define ARPHRD_6LOWPAN 825
+#define ARPHRD_VSOCKMON 826
#define ARPHRD_VOID 0xFFFF
#define ARPHRD_NONE 0xFFFE
#define ARPOP_REQUEST 1
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 35c2acd..7e6a72f 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -105,6 +105,7 @@
IFLA_BRIDGE_FLAGS,
IFLA_BRIDGE_MODE,
IFLA_BRIDGE_VLAN_INFO,
+ IFLA_BRIDGE_VLAN_TUNNEL_INFO,
__IFLA_BRIDGE_MAX,
};
#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
@@ -118,6 +119,14 @@
__u16 flags;
__u16 vid;
};
+enum {
+ IFLA_BRIDGE_VLAN_TUNNEL_UNSPEC,
+ IFLA_BRIDGE_VLAN_TUNNEL_ID,
+ IFLA_BRIDGE_VLAN_TUNNEL_VID,
+ IFLA_BRIDGE_VLAN_TUNNEL_FLAGS,
+ __IFLA_BRIDGE_VLAN_TUNNEL_MAX,
+};
+#define IFLA_BRIDGE_VLAN_TUNNEL_MAX (__IFLA_BRIDGE_VLAN_TUNNEL_MAX - 1)
struct bridge_vlan_xstats {
__u64 rx_bytes;
__u64 rx_packets;
diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h
index 591a5cc..846d238 100644
--- a/libc/kernel/uapi/linux/if_ether.h
+++ b/libc/kernel/uapi/linux/if_ether.h
@@ -75,6 +75,7 @@
#define ETH_P_NCSI 0x88F8
#define ETH_P_PRP 0x88FB
#define ETH_P_FCOE 0x8906
+#define ETH_P_IBOE 0x8915
#define ETH_P_TDLS 0x890D
#define ETH_P_FIP 0x8914
#define ETH_P_80221 0x8917
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 1397f5b..8ea790b 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -251,6 +251,9 @@
IFLA_BRPORT_MULTICAST_ROUTER,
IFLA_BRPORT_PAD,
IFLA_BRPORT_MCAST_FLOOD,
+ IFLA_BRPORT_MCAST_TO_UCAST,
+ IFLA_BRPORT_VLAN_TUNNEL,
+ IFLA_BRPORT_BCAST_FLOOD,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -427,11 +430,16 @@
__IFLA_PPP_MAX
};
#define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1)
+enum ifla_gtp_role {
+ GTP_ROLE_GGSN = 0,
+ GTP_ROLE_SGSN,
+};
enum {
IFLA_GTP_UNSPEC,
IFLA_GTP_FD0,
IFLA_GTP_FD1,
IFLA_GTP_PDP_HASHSIZE,
+ IFLA_GTP_ROLE,
__IFLA_GTP_MAX,
};
#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
@@ -665,6 +673,7 @@
IFLA_STATS_LINK_XSTATS,
IFLA_STATS_LINK_XSTATS_SLAVE,
IFLA_STATS_LINK_OFFLOAD_XSTATS,
+ IFLA_STATS_AF_SPEC,
__IFLA_STATS_MAX,
};
#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
@@ -682,7 +691,14 @@
};
#define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1)
#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0)
-#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST)
+#define XDP_FLAGS_SKB_MODE (1U << 1)
+#define XDP_FLAGS_DRV_MODE (1U << 2)
+#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE)
+enum {
+ XDP_ATTACHED_NONE = 0,
+ XDP_ATTACHED_DRV,
+ XDP_ATTACHED_SKB,
+};
enum {
IFLA_XDP_UNSPEC,
IFLA_XDP_FD,
diff --git a/libc/kernel/uapi/linux/if_packet.h b/libc/kernel/uapi/linux/if_packet.h
index d800a8f..61d0a3a 100644
--- a/libc/kernel/uapi/linux/if_packet.h
+++ b/libc/kernel/uapi/linux/if_packet.h
@@ -72,6 +72,7 @@
#define PACKET_FANOUT_CBPF 6
#define PACKET_FANOUT_EBPF 7
#define PACKET_FANOUT_FLAG_ROLLOVER 0x1000
+#define PACKET_FANOUT_FLAG_UNIQUEID 0x2000
#define PACKET_FANOUT_FLAG_DEFRAG 0x8000
struct tpacket_stats {
unsigned int tp_packets;
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index e1d5594..aaad4cb 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -85,6 +85,7 @@
IFLA_IPTUN_ENCAP_SPORT,
IFLA_IPTUN_ENCAP_DPORT,
IFLA_IPTUN_COLLECT_METADATA,
+ IFLA_IPTUN_FWMARK,
__IFLA_IPTUN_MAX,
};
#define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1)
@@ -132,6 +133,7 @@
IFLA_GRE_ENCAP_DPORT,
IFLA_GRE_COLLECT_METADATA,
IFLA_GRE_IGNORE_DF,
+ IFLA_GRE_FWMARK,
__IFLA_GRE_MAX,
};
#define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1)
@@ -143,6 +145,7 @@
IFLA_VTI_OKEY,
IFLA_VTI_LOCAL,
IFLA_VTI_REMOTE,
+ IFLA_VTI_FWMARK,
__IFLA_VTI_MAX,
};
#define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1)
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/ife.h
similarity index 68%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/ife.h
index 3064508..0cfc583 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/ife.h
@@ -16,19 +16,16 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
-#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
+#ifndef __UAPI_IFE_H
+#define __UAPI_IFE_H
+#define IFE_METAHDRLEN 2
+enum {
+ IFE_META_SKBMARK = 1,
+ IFE_META_HASHID,
+ IFE_META_PRIO,
+ IFE_META_QMAP,
+ IFE_META_TCINDEX,
+ __IFE_META_MAX
};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+#define IFE_META_MAX (__IFE_META_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/igmp.h b/libc/kernel/uapi/linux/igmp.h
index d1ba6b1..f5d1164 100644
--- a/libc/kernel/uapi/linux/igmp.h
+++ b/libc/kernel/uapi/linux/igmp.h
@@ -42,7 +42,7 @@
struct igmpv3_report {
__u8 type;
__u8 resv1;
- __be16 csum;
+ __sum16 csum;
__be16 resv2;
__be16 ngrec;
struct igmpv3_grec grec[0];
@@ -50,7 +50,7 @@
struct igmpv3_query {
__u8 type;
__u8 code;
- __be16 csum;
+ __sum16 csum;
__be32 group;
#ifdef __LITTLE_ENDIAN_BITFIELD
__u8 qrv : 3, suppress : 1, resv : 4;
diff --git a/libc/kernel/uapi/linux/iio/types.h b/libc/kernel/uapi/linux/iio/types.h
index ef0401d..3d4769d 100644
--- a/libc/kernel/uapi/linux/iio/types.h
+++ b/libc/kernel/uapi/linux/iio/types.h
@@ -50,6 +50,7 @@
IIO_ELECTRICALCONDUCTIVITY,
IIO_COUNT,
IIO_INDEX,
+ IIO_GRAVITY,
};
enum iio_modifier {
IIO_NO_MOD,
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index a599b7f..aea69f3 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -564,6 +564,7 @@
#define KEY_FASTREVERSE 0x275
#define KEY_SLOWREVERSE 0x276
#define KEY_DATA 0x277
+#define KEY_ONSCREEN_KEYBOARD 0x278
#define BTN_TRIGGER_HAPPY 0x2c0
#define BTN_TRIGGER_HAPPY1 0x2c0
#define BTN_TRIGGER_HAPPY2 0x2c1
diff --git a/libc/kernel/uapi/linux/ip6_tunnel.h b/libc/kernel/uapi/linux/ip6_tunnel.h
index c3564f3..b7df956 100644
--- a/libc/kernel/uapi/linux/ip6_tunnel.h
+++ b/libc/kernel/uapi/linux/ip6_tunnel.h
@@ -19,6 +19,8 @@
#ifndef _IP6_TUNNEL_H
#define _IP6_TUNNEL_H
#include <linux/types.h>
+#include <linux/if.h>
+#include <linux/in6.h>
#define IPV6_TLV_TNL_ENCAP_LIMIT 4
#define IPV6_DEFAULT_TNL_ENCAP_LIMIT 4
#define IP6_TNL_F_IGN_ENCAP_LIMIT 0x1
diff --git a/libc/kernel/uapi/linux/ipv6.h b/libc/kernel/uapi/linux/ipv6.h
index 125657c..d07fa06 100644
--- a/libc/kernel/uapi/linux/ipv6.h
+++ b/libc/kernel/uapi/linux/ipv6.h
@@ -137,6 +137,9 @@
DEVCONF_SEG6_ENABLED,
DEVCONF_SEG6_REQUIRE_HMAC,
DEVCONF_ENHANCED_DAD,
+ DEVCONF_ADDR_GEN_MODE,
+ DEVCONF_DISABLE_POLICY,
+ DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN,
DEVCONF_MAX
};
#endif
diff --git a/libc/kernel/uapi/linux/ipv6_route.h b/libc/kernel/uapi/linux/ipv6_route.h
index 56bc659..b7271a7 100644
--- a/libc/kernel/uapi/linux/ipv6_route.h
+++ b/libc/kernel/uapi/linux/ipv6_route.h
@@ -19,6 +19,7 @@
#ifndef _UAPI_LINUX_IPV6_ROUTE_H
#define _UAPI_LINUX_IPV6_ROUTE_H
#include <linux/types.h>
+#include <linux/in6.h>
#define RTF_DEFAULT 0x00010000
#define RTF_ALLONLINK 0x00020000
#define RTF_ADDRCONF 0x00040000
diff --git a/libc/kernel/uapi/linux/keyctl.h b/libc/kernel/uapi/linux/keyctl.h
index a988f49..0cc7f55 100644
--- a/libc/kernel/uapi/linux/keyctl.h
+++ b/libc/kernel/uapi/linux/keyctl.h
@@ -60,9 +60,16 @@
#define KEYCTL_INVALIDATE 21
#define KEYCTL_GET_PERSISTENT 22
#define KEYCTL_DH_COMPUTE 23
+#define KEYCTL_RESTRICT_KEYRING 29
struct keyctl_dh_params {
__s32 __linux_private;
__s32 prime;
__s32 base;
};
+struct keyctl_kdf_params {
+ char __user * hashname;
+ char __user * otherinfo;
+ __u32 otherinfolen;
+ __u32 __spare[8];
+};
#endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 01fbc0d..f61a08b 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -176,7 +176,8 @@
#define KVM_INTERNAL_ERROR_DELIVERY_EV 3
struct kvm_run {
__u8 request_interrupt_window;
- __u8 padding1[7];
+ __u8 immediate_exit;
+ __u8 padding1[6];
__u32 exit_reason;
__u8 ready_for_interrupt_injection;
__u8 if_flag;
@@ -528,10 +529,17 @@
__u32 pad;
struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
};
+struct kvm_ppc_resize_hpt {
+ __u64 flags;
+ __u32 shift;
+ __u32 pad;
+};
#define KVMIO 0xAE
#define KVM_VM_S390_UCONTROL 1
#define KVM_VM_PPC_HV 1
#define KVM_VM_PPC_PR 2
+#define KVM_VM_MIPS_TE 0
+#define KVM_VM_MIPS_VZ 1
#define KVM_S390_SIE_PAGE_OFFSET 1
#define KVM_GET_API_VERSION _IO(KVMIO, 0x00)
#define KVM_CREATE_VM _IO(KVMIO, 0x01)
@@ -691,6 +699,18 @@
#define KVM_CAP_S390_USER_INSTR0 130
#define KVM_CAP_MSI_DEVID 131
#define KVM_CAP_PPC_HTM 132
+#define KVM_CAP_SPAPR_RESIZE_HPT 133
+#define KVM_CAP_PPC_MMU_RADIX 134
+#define KVM_CAP_PPC_MMU_HASH_V3 135
+#define KVM_CAP_IMMEDIATE_EXIT 136
+#define KVM_CAP_MIPS_VZ 137
+#define KVM_CAP_MIPS_TE 138
+#define KVM_CAP_MIPS_64BIT 139
+#define KVM_CAP_S390_GS 140
+#define KVM_CAP_S390_AIS 141
+#define KVM_CAP_SPAPR_TCE_VFIO 142
+#define KVM_CAP_X86_GUEST_MWAIT 143
+#define KVM_CAP_ARM_USER_IRQ 144
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
__u32 irqchip;
@@ -843,6 +863,7 @@
#define KVM_DEV_VFIO_GROUP 1
#define KVM_DEV_VFIO_GROUP_ADD 1
#define KVM_DEV_VFIO_GROUP_DEL 2
+#define KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE 3
enum kvm_device_type {
KVM_DEV_TYPE_FSL_MPIC_20 = 1,
#define KVM_DEV_TYPE_FSL_MPIC_20 KVM_DEV_TYPE_FSL_MPIC_20
@@ -862,6 +883,10 @@
#define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS
KVM_DEV_TYPE_MAX,
};
+struct kvm_vfio_spapr_tce {
+ __s32 groupfd;
+ __s32 tablefd;
+};
#define KVM_SET_MEMORY_REGION _IOW(KVMIO, 0x40, struct kvm_memory_region)
#define KVM_CREATE_VCPU _IO(KVMIO, 0x41)
#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 0x42, struct kvm_dirty_log)
@@ -920,6 +945,10 @@
#define KVM_PPC_GET_HTAB_FD _IOW(KVMIO, 0xaa, struct kvm_get_htab_fd)
#define KVM_ARM_SET_DEVICE_ADDR _IOW(KVMIO, 0xab, struct kvm_arm_device_addr)
#define KVM_PPC_RTAS_DEFINE_TOKEN _IOW(KVMIO, 0xac, struct kvm_rtas_token_args)
+#define KVM_PPC_RESIZE_HPT_PREPARE _IOR(KVMIO, 0xad, struct kvm_ppc_resize_hpt)
+#define KVM_PPC_RESIZE_HPT_COMMIT _IOR(KVMIO, 0xae, struct kvm_ppc_resize_hpt)
+#define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg)
+#define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info)
#define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)
#define KVM_SET_DEVICE_ATTR _IOW(KVMIO, 0xe1, struct kvm_device_attr)
#define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr)
@@ -1024,4 +1053,7 @@
};
#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
+#define KVM_ARM_DEV_EL1_VTIMER (1 << 0)
+#define KVM_ARM_DEV_EL1_PTIMER (1 << 1)
+#define KVM_ARM_DEV_PMU (1 << 2)
#endif
diff --git a/libc/kernel/uapi/linux/kvm_para.h b/libc/kernel/uapi/linux/kvm_para.h
index 84b31a8..5035c23 100644
--- a/libc/kernel/uapi/linux/kvm_para.h
+++ b/libc/kernel/uapi/linux/kvm_para.h
@@ -22,6 +22,7 @@
#define KVM_EFAULT EFAULT
#define KVM_E2BIG E2BIG
#define KVM_EPERM EPERM
+#define KVM_EOPNOTSUPP 95
#define KVM_HC_VAPIC_POLL_IRQ 1
#define KVM_HC_MMU_OP 2
#define KVM_HC_FEATURES 3
@@ -30,5 +31,6 @@
#define KVM_HC_MIPS_GET_CLOCK_FREQ 6
#define KVM_HC_MIPS_EXIT_VM 7
#define KVM_HC_MIPS_CONSOLE_OUTPUT 8
+#define KVM_HC_CLOCK_PAIRING 9
#include <asm/kvm_para.h>
#endif
diff --git a/libc/kernel/uapi/linux/lightnvm.h b/libc/kernel/uapi/linux/lightnvm.h
index f589b1a..996d873 100644
--- a/libc/kernel/uapi/linux/lightnvm.h
+++ b/libc/kernel/uapi/linux/lightnvm.h
@@ -67,6 +67,9 @@
struct nvm_ioctl_create_simple s;
};
};
+enum {
+ NVM_TARGET_FACTORY = 1 << 0,
+};
struct nvm_ioctl_create {
char dev[DISK_NAME_LEN];
char tgttype[NVM_TTYPE_NAME_MAX];
@@ -93,6 +96,42 @@
char dev[DISK_NAME_LEN];
__u32 flags;
};
+struct nvm_user_vio {
+ __u8 opcode;
+ __u8 flags;
+ __u16 control;
+ __u16 nppas;
+ __u16 rsvd;
+ __u64 metadata;
+ __u64 addr;
+ __u64 ppa_list;
+ __u32 metadata_len;
+ __u32 data_len;
+ __u64 status;
+ __u32 result;
+ __u32 rsvd3[3];
+};
+struct nvm_passthru_vio {
+ __u8 opcode;
+ __u8 flags;
+ __u8 rsvd[2];
+ __u32 nsid;
+ __u32 cdw2;
+ __u32 cdw3;
+ __u64 metadata;
+ __u64 addr;
+ __u32 metadata_len;
+ __u32 data_len;
+ __u64 ppa_list;
+ __u16 nppas;
+ __u16 control;
+ __u32 cdw13;
+ __u32 cdw14;
+ __u32 cdw15;
+ __u64 status;
+ __u32 result;
+ __u32 timeout_ms;
+};
enum {
NVM_INFO_CMD = 0x20,
NVM_GET_DEVICES_CMD,
@@ -100,6 +139,9 @@
NVM_DEV_REMOVE_CMD,
NVM_DEV_INIT_CMD,
NVM_DEV_FACTORY_CMD,
+ NVM_DEV_VIO_ADMIN_CMD = 0x41,
+ NVM_DEV_VIO_CMD = 0x42,
+ NVM_DEV_VIO_USER_CMD = 0x43,
};
#define NVM_IOCTL 'L'
#define NVM_INFO _IOWR(NVM_IOCTL, NVM_INFO_CMD, struct nvm_ioctl_info)
@@ -108,6 +150,9 @@
#define NVM_DEV_REMOVE _IOW(NVM_IOCTL, NVM_DEV_REMOVE_CMD, struct nvm_ioctl_remove)
#define NVM_DEV_INIT _IOW(NVM_IOCTL, NVM_DEV_INIT_CMD, struct nvm_ioctl_dev_init)
#define NVM_DEV_FACTORY _IOW(NVM_IOCTL, NVM_DEV_FACTORY_CMD, struct nvm_ioctl_dev_factory)
+#define NVME_NVM_IOCTL_IO_VIO _IOWR(NVM_IOCTL, NVM_DEV_VIO_USER_CMD, struct nvm_passthru_vio)
+#define NVME_NVM_IOCTL_ADMIN_VIO _IOWR(NVM_IOCTL, NVM_DEV_VIO_ADMIN_CMD, struct nvm_passthru_vio)
+#define NVME_NVM_IOCTL_SUBMIT_VIO _IOWR(NVM_IOCTL, NVM_DEV_VIO_CMD, struct nvm_user_vio)
#define NVM_VERSION_MAJOR 1
#define NVM_VERSION_MINOR 0
#define NVM_VERSION_PATCHLEVEL 0
diff --git a/libc/kernel/uapi/linux/llc.h b/libc/kernel/uapi/linux/llc.h
index 41c4d84..e6f778f 100644
--- a/libc/kernel/uapi/linux/llc.h
+++ b/libc/kernel/uapi/linux/llc.h
@@ -19,6 +19,7 @@
#ifndef _UAPI__LINUX_LLC_H
#define _UAPI__LINUX_LLC_H
#include <linux/socket.h>
+#include <linux/if.h>
#define __LLC_SOCK_SIZE__ 16
struct sockaddr_llc {
__kernel_sa_family_t sllc_family;
diff --git a/libc/kernel/uapi/linux/media-bus-format.h b/libc/kernel/uapi/linux/media-bus-format.h
index b288c02..dd7fcc7 100644
--- a/libc/kernel/uapi/linux/media-bus-format.h
+++ b/libc/kernel/uapi/linux/media-bus-format.h
@@ -42,6 +42,9 @@
#define MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA 0x1012
#define MEDIA_BUS_FMT_ARGB8888_1X32 0x100d
#define MEDIA_BUS_FMT_RGB888_1X32_PADHI 0x100f
+#define MEDIA_BUS_FMT_RGB101010_1X30 0x1018
+#define MEDIA_BUS_FMT_RGB121212_1X36 0x1019
+#define MEDIA_BUS_FMT_RGB161616_1X48 0x101a
#define MEDIA_BUS_FMT_Y8_1X8 0x2001
#define MEDIA_BUS_FMT_UV8_1X8 0x2015
#define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002
@@ -73,12 +76,18 @@
#define MEDIA_BUS_FMT_YVYU10_1X20 0x200e
#define MEDIA_BUS_FMT_VUY8_1X24 0x2024
#define MEDIA_BUS_FMT_YUV8_1X24 0x2025
+#define MEDIA_BUS_FMT_UYYVYY8_0_5X24 0x2026
#define MEDIA_BUS_FMT_UYVY12_1X24 0x2020
#define MEDIA_BUS_FMT_VYUY12_1X24 0x2021
#define MEDIA_BUS_FMT_YUYV12_1X24 0x2022
#define MEDIA_BUS_FMT_YVYU12_1X24 0x2023
#define MEDIA_BUS_FMT_YUV10_1X30 0x2016
+#define MEDIA_BUS_FMT_UYYVYY10_0_5X30 0x2027
#define MEDIA_BUS_FMT_AYUV8_1X32 0x2017
+#define MEDIA_BUS_FMT_UYYVYY12_0_5X36 0x2028
+#define MEDIA_BUS_FMT_YUV12_1X36 0x2029
+#define MEDIA_BUS_FMT_YUV16_1X48 0x202a
+#define MEDIA_BUS_FMT_UYYVYY16_0_5X48 0x202b
#define MEDIA_BUS_FMT_SBGGR8_1X8 0x3001
#define MEDIA_BUS_FMT_SGBRG8_1X8 0x3013
#define MEDIA_BUS_FMT_SGRBG8_1X8 0x3002
diff --git a/libc/kernel/uapi/linux/mpls.h b/libc/kernel/uapi/linux/mpls.h
index 4938f42..86d8e07 100644
--- a/libc/kernel/uapi/linux/mpls.h
+++ b/libc/kernel/uapi/linux/mpls.h
@@ -40,4 +40,21 @@
#define MPLS_LABEL_OAMALERT 14
#define MPLS_LABEL_EXTENSION 15
#define MPLS_LABEL_FIRST_UNRESERVED 16
+enum {
+ MPLS_STATS_UNSPEC,
+ MPLS_STATS_LINK,
+ __MPLS_STATS_MAX,
+};
+#define MPLS_STATS_MAX (__MPLS_STATS_MAX - 1)
+struct mpls_link_stats {
+ __u64 rx_packets;
+ __u64 tx_packets;
+ __u64 rx_bytes;
+ __u64 tx_bytes;
+ __u64 rx_errors;
+ __u64 tx_errors;
+ __u64 rx_dropped;
+ __u64 tx_dropped;
+ __u64 rx_noroute;
+};
#endif
diff --git a/libc/kernel/uapi/linux/mpls_iptunnel.h b/libc/kernel/uapi/linux/mpls_iptunnel.h
index 773a49f..473cb0d 100644
--- a/libc/kernel/uapi/linux/mpls_iptunnel.h
+++ b/libc/kernel/uapi/linux/mpls_iptunnel.h
@@ -21,6 +21,7 @@
enum {
MPLS_IPTUNNEL_UNSPEC,
MPLS_IPTUNNEL_DST,
+ MPLS_IPTUNNEL_TTL,
__MPLS_IPTUNNEL_MAX,
};
#define MPLS_IPTUNNEL_MAX (__MPLS_IPTUNNEL_MAX - 1)
diff --git a/libc/kernel/uapi/linux/mqueue.h b/libc/kernel/uapi/linux/mqueue.h
index dbd862f..a540830 100644
--- a/libc/kernel/uapi/linux/mqueue.h
+++ b/libc/kernel/uapi/linux/mqueue.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef _LINUX_MQUEUE_H
#define _LINUX_MQUEUE_H
+#include <linux/types.h>
#define MQ_PRIO_MAX 32768
#define MQ_BYTES_MAX 819200
struct mq_attr {
diff --git a/libc/kernel/uapi/linux/mroute.h b/libc/kernel/uapi/linux/mroute.h
index 5a09edd..9f4c937 100644
--- a/libc/kernel/uapi/linux/mroute.h
+++ b/libc/kernel/uapi/linux/mroute.h
@@ -20,6 +20,7 @@
#define _UAPI__LINUX_MROUTE_H
#include <linux/sockios.h>
#include <linux/types.h>
+#include <linux/in.h>
#define MRT_BASE 200
#define MRT_INIT (MRT_BASE)
#define MRT_DONE (MRT_BASE + 1)
diff --git a/libc/kernel/uapi/linux/mroute6.h b/libc/kernel/uapi/linux/mroute6.h
index 88b8ff7..d9c86bf 100644
--- a/libc/kernel/uapi/linux/mroute6.h
+++ b/libc/kernel/uapi/linux/mroute6.h
@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sockios.h>
+#include <linux/in6.h>
#define MRT6_BASE 200
#define MRT6_INIT (MRT6_BASE)
#define MRT6_DONE (MRT6_BASE + 1)
diff --git a/libc/kernel/uapi/linux/nbd-netlink.h b/libc/kernel/uapi/linux/nbd-netlink.h
new file mode 100644
index 0000000..9faf689
--- /dev/null
+++ b/libc/kernel/uapi/linux/nbd-netlink.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 _UAPILINUX_NBD_NETLINK_H
+#define _UAPILINUX_NBD_NETLINK_H
+#define NBD_GENL_FAMILY_NAME "nbd"
+#define NBD_GENL_VERSION 0x1
+#define NBD_GENL_MCAST_GROUP_NAME "nbd_mc_group"
+enum {
+ NBD_ATTR_UNSPEC,
+ NBD_ATTR_INDEX,
+ NBD_ATTR_SIZE_BYTES,
+ NBD_ATTR_BLOCK_SIZE_BYTES,
+ NBD_ATTR_TIMEOUT,
+ NBD_ATTR_SERVER_FLAGS,
+ NBD_ATTR_CLIENT_FLAGS,
+ NBD_ATTR_SOCKETS,
+ NBD_ATTR_DEAD_CONN_TIMEOUT,
+ NBD_ATTR_DEVICE_LIST,
+ __NBD_ATTR_MAX,
+};
+#define NBD_ATTR_MAX (__NBD_ATTR_MAX - 1)
+enum {
+ NBD_DEVICE_ITEM_UNSPEC,
+ NBD_DEVICE_ITEM,
+ __NBD_DEVICE_ITEM_MAX,
+};
+#define NBD_DEVICE_ITEM_MAX (__NBD_DEVICE_ITEM_MAX - 1)
+enum {
+ NBD_DEVICE_UNSPEC,
+ NBD_DEVICE_INDEX,
+ NBD_DEVICE_CONNECTED,
+ __NBD_DEVICE_MAX,
+};
+#define NBD_DEVICE_ATTR_MAX (__NBD_DEVICE_MAX - 1)
+enum {
+ NBD_SOCK_ITEM_UNSPEC,
+ NBD_SOCK_ITEM,
+ __NBD_SOCK_ITEM_MAX,
+};
+#define NBD_SOCK_ITEM_MAX (__NBD_SOCK_ITEM_MAX - 1)
+enum {
+ NBD_SOCK_UNSPEC,
+ NBD_SOCK_FD,
+ __NBD_SOCK_MAX,
+};
+#define NBD_SOCK_MAX (__NBD_SOCK_MAX - 1)
+enum {
+ NBD_CMD_UNSPEC,
+ NBD_CMD_CONNECT,
+ NBD_CMD_DISCONNECT,
+ NBD_CMD_RECONFIGURE,
+ NBD_CMD_LINK_DEAD,
+ NBD_CMD_STATUS,
+ __NBD_CMD_MAX,
+};
+#define NBD_CMD_MAX (__NBD_CMD_MAX - 1)
+#endif
diff --git a/libc/kernel/uapi/linux/nbd.h b/libc/kernel/uapi/linux/nbd.h
index e8fc47c..50079fa 100644
--- a/libc/kernel/uapi/linux/nbd.h
+++ b/libc/kernel/uapi/linux/nbd.h
@@ -42,6 +42,7 @@
#define NBD_FLAG_SEND_FLUSH (1 << 2)
#define NBD_FLAG_SEND_TRIM (1 << 5)
#define NBD_FLAG_CAN_MULTI_CONN (1 << 8)
+#define NBD_CFLAG_DESTROY_ON_DISCONNECT (1 << 0)
#define NBD_REQUEST_MAGIC 0x25609513
#define NBD_REPLY_MAGIC 0x67446698
struct nbd_request {
diff --git a/libc/kernel/uapi/linux/ndctl.h b/libc/kernel/uapi/linux/ndctl.h
index bb51eea..cfe5c9c 100644
--- a/libc/kernel/uapi/linux/ndctl.h
+++ b/libc/kernel/uapi/linux/ndctl.h
@@ -153,6 +153,7 @@
enum {
ND_ARS_VOLATILE = 1,
ND_ARS_PERSISTENT = 2,
+ ND_CONFIG_LOCKED = 1,
};
#define ND_IOCTL 'N'
#define ND_IOCTL_SMART _IOWR(ND_IOCTL, ND_CMD_SMART, struct nd_cmd_smart)
diff --git a/libc/kernel/uapi/linux/neighbour.h b/libc/kernel/uapi/linux/neighbour.h
index d239e72..1a322de 100644
--- a/libc/kernel/uapi/linux/neighbour.h
+++ b/libc/kernel/uapi/linux/neighbour.h
@@ -41,6 +41,7 @@
NDA_IFINDEX,
NDA_MASTER,
NDA_LINK_NETNSID,
+ NDA_SRC_VNI,
__NDA_MAX
};
#define NDA_MAX (__NDA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/netconf.h b/libc/kernel/uapi/linux/netconf.h
index 981badd..4f86757 100644
--- a/libc/kernel/uapi/linux/netconf.h
+++ b/libc/kernel/uapi/linux/netconf.h
@@ -31,6 +31,7 @@
NETCONFA_MC_FORWARDING,
NETCONFA_PROXY_NEIGH,
NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
+ NETCONFA_INPUT,
__NETCONFA_MAX
};
#define NETCONFA_MAX (__NETCONFA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/netfilter.h b/libc/kernel/uapi/linux/netfilter.h
index 6f6b998..5538869 100644
--- a/libc/kernel/uapi/linux/netfilter.h
+++ b/libc/kernel/uapi/linux/netfilter.h
@@ -20,7 +20,6 @@
#define _UAPI__LINUX_NETFILTER_H
#include <linux/types.h>
#include <linux/compiler.h>
-#include <linux/sysctl.h>
#include <linux/in.h>
#include <linux/in6.h>
#define NF_DROP 0
diff --git a/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h b/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
index e08769c..5192a54 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
@@ -30,7 +30,7 @@
};
#define NF_CT_STATE_INVALID_BIT (1 << 0)
#define NF_CT_STATE_BIT(ctinfo) (1 << ((ctinfo) % IP_CT_IS_REPLY + 1))
-#define NF_CT_STATE_UNTRACKED_BIT (1 << (IP_CT_NUMBER + 1))
+#define NF_CT_STATE_UNTRACKED_BIT (1 << (IP_CT_UNTRACKED + 1))
enum ip_conntrack_status {
IPS_EXPECTED_BIT = 0,
IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
@@ -62,6 +62,8 @@
IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
IPS_HELPER_BIT = 13,
IPS_HELPER = (1 << IPS_HELPER_BIT),
+ IPS_UNCHANGEABLE_MASK = (IPS_NAT_DONE_MASK | IPS_NAT_MASK | IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING | IPS_SEQ_ADJUST | IPS_TEMPLATE),
+ __IPS_MAX_BIT = 14,
};
enum ip_conntrack_events {
IPCT_NEW,
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 7cadf61..c090f94 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -131,6 +131,7 @@
NFTA_RULE_POSITION,
NFTA_RULE_USERDATA,
NFTA_RULE_PAD,
+ NFTA_RULE_ID,
__NFTA_RULE_MAX
};
#define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)
@@ -356,12 +357,23 @@
__NFTA_PAYLOAD_MAX
};
#define NFTA_PAYLOAD_MAX (__NFTA_PAYLOAD_MAX - 1)
+enum nft_exthdr_flags {
+ NFT_EXTHDR_F_PRESENT = (1 << 0),
+};
+enum nft_exthdr_op {
+ NFT_EXTHDR_OP_IPV6,
+ NFT_EXTHDR_OP_TCPOPT,
+ __NFT_EXTHDR_OP_MAX
+};
+#define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1)
enum nft_exthdr_attributes {
NFTA_EXTHDR_UNSPEC,
NFTA_EXTHDR_DREG,
NFTA_EXTHDR_TYPE,
NFTA_EXTHDR_OFFSET,
NFTA_EXTHDR_LEN,
+ NFTA_EXTHDR_FLAGS,
+ NFTA_EXTHDR_OP,
__NFTA_EXTHDR_MAX
};
#define NFTA_EXTHDR_MAX (__NFTA_EXTHDR_MAX - 1)
@@ -397,6 +409,10 @@
NFT_RT_NEXTHOP4,
NFT_RT_NEXTHOP6,
};
+enum nft_hash_types {
+ NFT_HASH_JENKINS,
+ NFT_HASH_SYM,
+};
enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
NFTA_HASH_SREG,
@@ -405,6 +421,7 @@
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
NFTA_HASH_OFFSET,
+ NFTA_HASH_TYPE,
__NFTA_HASH_MAX,
};
#define NFTA_HASH_MAX (__NFTA_HASH_MAX - 1)
@@ -440,6 +457,9 @@
NFT_CT_LABELS,
NFT_CT_PKTS,
NFT_CT_BYTES,
+ NFT_CT_AVGPKT,
+ NFT_CT_ZONE,
+ NFT_CT_EVENTMASK,
};
enum nft_ct_attributes {
NFTA_CT_UNSPEC,
@@ -615,11 +635,21 @@
NFTA_FIB_F_MARK = 1 << 2,
NFTA_FIB_F_IIF = 1 << 3,
NFTA_FIB_F_OIF = 1 << 4,
+ NFTA_FIB_F_PRESENT = 1 << 5,
};
+enum nft_ct_helper_attributes {
+ NFTA_CT_HELPER_UNSPEC,
+ NFTA_CT_HELPER_NAME,
+ NFTA_CT_HELPER_L3PROTO,
+ NFTA_CT_HELPER_L4PROTO,
+ __NFTA_CT_HELPER_MAX,
+};
+#define NFTA_CT_HELPER_MAX (__NFTA_CT_HELPER_MAX - 1)
#define NFT_OBJECT_UNSPEC 0
#define NFT_OBJECT_COUNTER 1
#define NFT_OBJECT_QUOTA 2
-#define __NFT_OBJECT_MAX 3
+#define NFT_OBJECT_CT_HELPER 3
+#define __NFT_OBJECT_MAX 4
#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
enum nft_object_attributes {
NFTA_OBJ_UNSPEC,
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink.h b/libc/kernel/uapi/linux/netfilter/nfnetlink.h
index 8dffa49..9145552 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink.h
@@ -67,4 +67,10 @@
#define NFNL_SUBSYS_COUNT 12
#define NFNL_MSG_BATCH_BEGIN NLMSG_MIN_TYPE
#define NFNL_MSG_BATCH_END NLMSG_MIN_TYPE + 1
+enum nfnl_batch_attributes {
+ NFNL_BATCH_UNSPEC,
+ NFNL_BATCH_GENID,
+ __NFNL_BATCH_MAX
+};
+#define NFNL_BATCH_MAX (__NFNL_BATCH_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
index b3ebb3b..75fa359 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
@@ -47,7 +47,7 @@
NFQA_VLAN_TCI,
__NFQA_VLAN_MAX,
};
-#define NFQA_VLAN_MAX (__NFQA_VLAN_MAX + 1)
+#define NFQA_VLAN_MAX (__NFQA_VLAN_MAX - 1)
enum nfqnl_attr_type {
NFQA_UNSPEC,
NFQA_PACKET_HDR,
diff --git a/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h b/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h
index 0f4e931..c9d62f3 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h
@@ -19,6 +19,7 @@
#ifndef _UAPI_XT_HASHLIMIT_H
#define _UAPI_XT_HASHLIMIT_H
#include <linux/types.h>
+#include <linux/limits.h>
#include <linux/if.h>
#define XT_HASHLIMIT_SCALE 10000
#define XT_HASHLIMIT_SCALE_v2 1000000llu
diff --git a/libc/kernel/uapi/linux/netlink.h b/libc/kernel/uapi/linux/netlink.h
index 1352326..4eb428a 100644
--- a/libc/kernel/uapi/linux/netlink.h
+++ b/libc/kernel/uapi/linux/netlink.h
@@ -42,6 +42,7 @@
#define NETLINK_ECRYPTFS 19
#define NETLINK_RDMA 20
#define NETLINK_CRYPTO 21
+#define NETLINK_SMC 22
#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG
#define MAX_LINKS 32
struct sockaddr_nl {
@@ -57,12 +58,12 @@
__u32 nlmsg_seq;
__u32 nlmsg_pid;
};
-#define NLM_F_REQUEST 1
-#define NLM_F_MULTI 2
-#define NLM_F_ACK 4
-#define NLM_F_ECHO 8
-#define NLM_F_DUMP_INTR 16
-#define NLM_F_DUMP_FILTERED 32
+#define NLM_F_REQUEST 0x01
+#define NLM_F_MULTI 0x02
+#define NLM_F_ACK 0x04
+#define NLM_F_ECHO 0x08
+#define NLM_F_DUMP_INTR 0x10
+#define NLM_F_DUMP_FILTERED 0x20
#define NLM_F_ROOT 0x100
#define NLM_F_MATCH 0x200
#define NLM_F_ATOMIC 0x400
@@ -71,6 +72,8 @@
#define NLM_F_EXCL 0x200
#define NLM_F_CREATE 0x400
#define NLM_F_APPEND 0x800
+#define NLM_F_CAPPED 0x100
+#define NLM_F_ACK_TLVS 0x200
#define NLMSG_ALIGNTO 4U
#define NLMSG_ALIGN(len) (((len) + NLMSG_ALIGNTO - 1) & ~(NLMSG_ALIGNTO - 1))
#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
@@ -89,6 +92,14 @@
int error;
struct nlmsghdr msg;
};
+enum nlmsgerr_attrs {
+ NLMSGERR_ATTR_UNUSED,
+ NLMSGERR_ATTR_MSG,
+ NLMSGERR_ATTR_OFFS,
+ NLMSGERR_ATTR_COOKIE,
+ __NLMSGERR_ATTR_MAX,
+ NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
+};
#define NETLINK_ADD_MEMBERSHIP 1
#define NETLINK_DROP_MEMBERSHIP 2
#define NETLINK_PKTINFO 3
@@ -99,6 +110,7 @@
#define NETLINK_LISTEN_ALL_NSID 8
#define NETLINK_LIST_MEMBERSHIPS 9
#define NETLINK_CAP_ACK 10
+#define NETLINK_EXT_ACK 11
struct nl_pktinfo {
__u32 group;
};
diff --git a/libc/kernel/uapi/linux/netlink_diag.h b/libc/kernel/uapi/linux/netlink_diag.h
index 7a91ee4..afe1521 100644
--- a/libc/kernel/uapi/linux/netlink_diag.h
+++ b/libc/kernel/uapi/linux/netlink_diag.h
@@ -49,6 +49,7 @@
NETLINK_DIAG_GROUPS,
NETLINK_DIAG_RX_RING,
NETLINK_DIAG_TX_RING,
+ NETLINK_DIAG_FLAGS,
__NETLINK_DIAG_MAX,
};
#define NETLINK_DIAG_MAX (__NETLINK_DIAG_MAX - 1)
@@ -56,4 +57,11 @@
#define NDIAG_SHOW_MEMINFO 0x00000001
#define NDIAG_SHOW_GROUPS 0x00000002
#define NDIAG_SHOW_RING_CFG 0x00000004
+#define NDIAG_SHOW_FLAGS 0x00000008
+#define NDIAG_FLAG_CB_RUNNING 0x00000001
+#define NDIAG_FLAG_PKTINFO 0x00000002
+#define NDIAG_FLAG_BROADCAST_ERROR 0x00000004
+#define NDIAG_FLAG_NO_ENOBUFS 0x00000008
+#define NDIAG_FLAG_LISTEN_ALL_NSID 0x00000010
+#define NDIAG_FLAG_CAP_ACK 0x00000020
#endif
diff --git a/libc/kernel/uapi/linux/nfsd/cld.h b/libc/kernel/uapi/linux/nfsd/cld.h
index bcabb31..82651d1 100644
--- a/libc/kernel/uapi/linux/nfsd/cld.h
+++ b/libc/kernel/uapi/linux/nfsd/cld.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef _NFSD_CLD_H
#define _NFSD_CLD_H
+#include <linux/types.h>
#define CLD_UPCALL_VERSION 1
#define NFS4_OPAQUE_LIMIT 1024
enum cld_command {
@@ -27,16 +28,16 @@
Cld_GraceDone,
};
struct cld_name {
- uint16_t cn_len;
+ __u16 cn_len;
unsigned char cn_id[NFS4_OPAQUE_LIMIT];
} __attribute__((packed));
struct cld_msg {
- uint8_t cm_vers;
- uint8_t cm_cmd;
- int16_t cm_status;
- uint32_t cm_xid;
+ __u8 cm_vers;
+ __u8 cm_cmd;
+ __s16 cm_status;
+ __u32 cm_xid;
union {
- int64_t cm_gracetime;
+ __s64 cm_gracetime;
struct cld_name cm_name;
} __attribute__((packed)) cm_u;
} __attribute__((packed));
diff --git a/libc/kernel/uapi/linux/nfsd/export.h b/libc/kernel/uapi/linux/nfsd/export.h
index 2779e97..4716fb1 100644
--- a/libc/kernel/uapi/linux/nfsd/export.h
+++ b/libc/kernel/uapi/linux/nfsd/export.h
@@ -29,6 +29,7 @@
#define NFSEXP_ASYNC 0x0010
#define NFSEXP_GATHERED_WRITES 0x0020
#define NFSEXP_NOREADDIRPLUS 0x0040
+#define NFSEXP_SECURITY_LABEL 0x0080
#define NFSEXP_NOHIDE 0x0200
#define NFSEXP_NOSUBTREECHECK 0x0400
#define NFSEXP_NOAUTHNLM 0x0800
@@ -38,6 +39,6 @@
#define NFSEXP_NOACL 0x8000
#define NFSEXP_V4ROOT 0x10000
#define NFSEXP_PNFS 0x20000
-#define NFSEXP_ALLFLAGS 0x3FE7F
+#define NFSEXP_ALLFLAGS 0x3FEFF
#define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH | NFSEXP_ALLSQUASH | NFSEXP_INSECURE_PORT)
#endif
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 562e429..103b9da 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -411,13 +411,24 @@
NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY,
NL80211_ATTR_MESH_PEER_AID,
NL80211_ATTR_NAN_MASTER_PREF,
- NL80211_ATTR_NAN_DUAL,
+ NL80211_ATTR_BANDS,
NL80211_ATTR_NAN_FUNC,
NL80211_ATTR_NAN_MATCH,
NL80211_ATTR_FILS_KEK,
NL80211_ATTR_FILS_NONCES,
NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED,
NL80211_ATTR_BSSID,
+ NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
+ NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
+ NL80211_ATTR_TIMEOUT_REASON,
+ NL80211_ATTR_FILS_ERP_USERNAME,
+ NL80211_ATTR_FILS_ERP_REALM,
+ NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
+ NL80211_ATTR_FILS_ERP_RRK,
+ NL80211_ATTR_FILS_CACHE_ID,
+ NL80211_ATTR_PMK,
+ NL80211_ATTR_SCHED_SCAN_MULTI,
+ NL80211_ATTR_SCHED_SCAN_MAX_REQS,
__NL80211_ATTR_AFTER_LAST,
NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -669,6 +680,9 @@
__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID,
NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
+ NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI,
+ NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST,
+ NL80211_SCHED_SCAN_MATCH_ATTR_BSSID,
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
NL80211_SCHED_SCAN_MATCH_ATTR_MAX = __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1
};
@@ -948,6 +962,7 @@
NL80211_ATTR_CQM_TXE_PKTS,
NL80211_ATTR_CQM_TXE_INTVL,
NL80211_ATTR_CQM_BEACON_LOSS_EVENT,
+ NL80211_ATTR_CQM_RSSI_LEVEL,
__NL80211_ATTR_CQM_AFTER_LAST,
NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1
};
@@ -1167,6 +1182,11 @@
NL80211_EXT_FEATURE_BEACON_RATE_HT,
NL80211_EXT_FEATURE_BEACON_RATE_VHT,
NL80211_EXT_FEATURE_FILS_STA,
+ NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA,
+ NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,
+ NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
+ NL80211_EXT_FEATURE_CQM_RSSI_LIST,
+ NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
NUM_NL80211_EXT_FEATURES,
MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
};
@@ -1180,6 +1200,12 @@
NL80211_CONN_FAIL_MAX_CLIENTS,
NL80211_CONN_FAIL_BLOCKED_CLIENT,
};
+enum nl80211_timeout_reason {
+ NL80211_TIMEOUT_UNSPECIFIED,
+ NL80211_TIMEOUT_SCAN,
+ NL80211_TIMEOUT_AUTH,
+ NL80211_TIMEOUT_ASSOC,
+};
enum nl80211_scan_flags {
NL80211_SCAN_FLAG_LOW_PRIORITY = 1 << 0,
NL80211_SCAN_FLAG_FLUSH = 1 << 1,
@@ -1202,6 +1228,7 @@
NL80211_RADAR_CAC_FINISHED,
NL80211_RADAR_CAC_ABORTED,
NL80211_RADAR_NOP_FINISHED,
+ NL80211_RADAR_PRE_CAC_EXPIRED,
};
enum nl80211_dfs_state {
NL80211_DFS_USABLE,
@@ -1251,11 +1278,6 @@
__NL80211_BSS_SELECT_ATTR_AFTER_LAST,
NL80211_BSS_SELECT_ATTR_MAX = __NL80211_BSS_SELECT_ATTR_AFTER_LAST - 1
};
-enum nl80211_nan_dual_band_conf {
- NL80211_NAN_BAND_DEFAULT = 1 << 0,
- NL80211_NAN_BAND_2GHZ = 1 << 1,
- NL80211_NAN_BAND_5GHZ = 1 << 2,
-};
enum nl80211_nan_function_type {
NL80211_NAN_FUNC_PUBLISH,
NL80211_NAN_FUNC_SUBSCRIBE,
diff --git a/libc/kernel/uapi/linux/nsfs.h b/libc/kernel/uapi/linux/nsfs.h
index 0a35074..d32d31c 100644
--- a/libc/kernel/uapi/linux/nsfs.h
+++ b/libc/kernel/uapi/linux/nsfs.h
@@ -22,4 +22,6 @@
#define NSIO 0xb7
#define NS_GET_USERNS _IO(NSIO, 0x1)
#define NS_GET_PARENT _IO(NSIO, 0x2)
+#define NS_GET_NSTYPE _IO(NSIO, 0x3)
+#define NS_GET_OWNER_UID _IO(NSIO, 0x4)
#endif
diff --git a/libc/kernel/uapi/linux/nubus.h b/libc/kernel/uapi/linux/nubus.h
index 5c80c81..530005b 100644
--- a/libc/kernel/uapi/linux/nubus.h
+++ b/libc/kernel/uapi/linux/nubus.h
@@ -64,13 +64,15 @@
NUBUS_DRHW_SIGMA_CLRMAX = 0x0007,
NUBUS_DRHW_APPLE_SE30 = 0x0009,
NUBUS_DRHW_APPLE_HRVC = 0x0013,
+ NUBUS_DRHW_APPLE_MVC = 0x0014,
NUBUS_DRHW_APPLE_PVC = 0x0017,
NUBUS_DRHW_APPLE_RBV1 = 0x0018,
NUBUS_DRHW_APPLE_MDC = 0x0019,
+ NUBUS_DRHW_APPLE_VSC = 0x0020,
NUBUS_DRHW_APPLE_SONORA = 0x0022,
+ NUBUS_DRHW_APPLE_JET = 0x0029,
NUBUS_DRHW_APPLE_24AC = 0x002b,
NUBUS_DRHW_APPLE_VALKYRIE = 0x002e,
- NUBUS_DRHW_APPLE_JET = 0x0029,
NUBUS_DRHW_SMAC_GFX = 0x0105,
NUBUS_DRHW_RASTER_CB264 = 0x013B,
NUBUS_DRHW_MICRON_XCEED = 0x0146,
diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h
index 54c76d7..7247171 100644
--- a/libc/kernel/uapi/linux/openvswitch.h
+++ b/libc/kernel/uapi/linux/openvswitch.h
@@ -180,6 +180,8 @@
OVS_KEY_ATTR_CT_ZONE,
OVS_KEY_ATTR_CT_MARK,
OVS_KEY_ATTR_CT_LABELS,
+ OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4,
+ OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6,
__OVS_KEY_ATTR_MAX
};
#define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1)
@@ -265,9 +267,13 @@
__u8 nd_sll[ETH_ALEN];
__u8 nd_tll[ETH_ALEN];
};
-#define OVS_CT_LABELS_LEN 16
+#define OVS_CT_LABELS_LEN_32 4
+#define OVS_CT_LABELS_LEN (OVS_CT_LABELS_LEN_32 * sizeof(__u32))
struct ovs_key_ct_labels {
- __u8 ct_labels[OVS_CT_LABELS_LEN];
+ union {
+ __u8 ct_labels[OVS_CT_LABELS_LEN];
+ __u32 ct_labels_32[OVS_CT_LABELS_LEN_32];
+ };
};
#define OVS_CS_F_NEW 0x01
#define OVS_CS_F_ESTABLISHED 0x02
@@ -278,6 +284,20 @@
#define OVS_CS_F_SRC_NAT 0x40
#define OVS_CS_F_DST_NAT 0x80
#define OVS_CS_F_NAT_MASK (OVS_CS_F_SRC_NAT | OVS_CS_F_DST_NAT)
+struct ovs_key_ct_tuple_ipv4 {
+ __be32 ipv4_src;
+ __be32 ipv4_dst;
+ __be16 src_port;
+ __be16 dst_port;
+ __u8 ipv4_proto;
+};
+struct ovs_key_ct_tuple_ipv6 {
+ __be32 ipv6_src[4];
+ __be32 ipv6_dst[4];
+ __be16 src_port;
+ __be16 dst_port;
+ __u8 ipv6_proto;
+};
enum ovs_flow_attr {
OVS_FLOW_ATTR_UNSPEC,
OVS_FLOW_ATTR_KEY,
@@ -339,6 +359,8 @@
OVS_CT_ATTR_LABELS,
OVS_CT_ATTR_HELPER,
OVS_CT_ATTR_NAT,
+ OVS_CT_ATTR_FORCE_COMMIT,
+ OVS_CT_ATTR_EVENTMASK,
__OVS_CT_ATTR_MAX
};
#define OVS_CT_ATTR_MAX (__OVS_CT_ATTR_MAX - 1)
diff --git a/libc/kernel/uapi/linux/packet_diag.h b/libc/kernel/uapi/linux/packet_diag.h
index f0b7525..35d5413 100644
--- a/libc/kernel/uapi/linux/packet_diag.h
+++ b/libc/kernel/uapi/linux/packet_diag.h
@@ -70,7 +70,7 @@
__u32 pdmc_count;
__u16 pdmc_type;
__u16 pdmc_alen;
- __u8 pdmc_addr[MAX_ADDR_LEN];
+ __u8 pdmc_addr[32];
};
struct packet_diag_ring {
__u32 pdr_block_size;
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index d56b310..baa9421 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -86,7 +86,7 @@
#define PCI_SUBSYSTEM_ID 0x2e
#define PCI_ROM_ADDRESS 0x30
#define PCI_ROM_ADDRESS_ENABLE 0x01
-#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
+#define PCI_ROM_ADDRESS_MASK (~0x7ffU)
#define PCI_CAPABILITY_LIST 0x34
#define PCI_INTERRUPT_LINE 0x3c
#define PCI_INTERRUPT_PIN 0x3d
@@ -533,6 +533,7 @@
#define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f
#define PCI_EXP_DEVCTL2_ARI 0x0020
#define PCI_EXP_DEVCTL2_ATOMIC_REQ 0x0040
+#define PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK 0x0080
#define PCI_EXP_DEVCTL2_IDO_REQ_EN 0x0100
#define PCI_EXP_DEVCTL2_IDO_CMP_EN 0x0200
#define PCI_EXP_DEVCTL2_LTR_EN 0x0400
@@ -582,6 +583,7 @@
#define PCI_EXT_CAP_ID_PMUX 0x1A
#define PCI_EXT_CAP_ID_PASID 0x1B
#define PCI_EXT_CAP_ID_DPC 0x1D
+#define PCI_EXT_CAP_ID_L1SS 0x1E
#define PCI_EXT_CAP_ID_PTM 0x1F
#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PTM
#define PCI_EXT_CAP_DSN_SIZEOF 12
@@ -819,6 +821,7 @@
#define PCI_EXP_DPC_STATUS 8
#define PCI_EXP_DPC_STATUS_TRIGGER 0x01
#define PCI_EXP_DPC_STATUS_INTERRUPT 0x08
+#define PCI_EXP_DPC_RP_BUSY 0x10
#define PCI_EXP_DPC_SOURCE_ID 10
#define PCI_PTM_CAP 0x04
#define PCI_PTM_CAP_REQ 0x00000001
@@ -827,4 +830,17 @@
#define PCI_PTM_CTRL 0x08
#define PCI_PTM_CTRL_ENABLE 0x00000001
#define PCI_PTM_CTRL_ROOT 0x00000002
+#define PCI_L1SS_CAP 4
+#define PCI_L1SS_CAP_PCIPM_L1_2 1
+#define PCI_L1SS_CAP_PCIPM_L1_1 2
+#define PCI_L1SS_CAP_ASPM_L1_2 4
+#define PCI_L1SS_CAP_ASPM_L1_1 8
+#define PCI_L1SS_CAP_L1_PM_SS 16
+#define PCI_L1SS_CTL1 8
+#define PCI_L1SS_CTL1_PCIPM_L1_2 1
+#define PCI_L1SS_CTL1_PCIPM_L1_1 2
+#define PCI_L1SS_CTL1_ASPM_L1_2 4
+#define PCI_L1SS_CTL1_ASPM_L1_1 8
+#define PCI_L1SS_CTL1_L1SS_MASK 0x0000000F
+#define PCI_L1SS_CTL2 0xC
#endif
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/pcitest.h
similarity index 68%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/pcitest.h
index 3064508..e6c0264 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/pcitest.h
@@ -16,19 +16,12 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
-#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
-};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+#ifndef __UAPI_LINUX_PCITEST_H
+#define __UAPI_LINUX_PCITEST_H
+#define PCITEST_BAR _IO('P', 0x1)
+#define PCITEST_LEGACY_IRQ _IO('P', 0x2)
+#define PCITEST_MSI _IOW('P', 0x3, int)
+#define PCITEST_WRITE _IOW('P', 0x4, unsigned long)
+#define PCITEST_READ _IOW('P', 0x5, unsigned long)
+#define PCITEST_COPY _IOW('P', 0x6, unsigned long)
#endif
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index dedb9e5..8adad9c 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -180,7 +180,7 @@
};
__u64 sample_type;
__u64 read_format;
- __u64 disabled : 1, inherit : 1, pinned : 1, exclusive : 1, exclude_user : 1, exclude_kernel : 1, exclude_hv : 1, exclude_idle : 1, mmap : 1, comm : 1, freq : 1, inherit_stat : 1, enable_on_exec : 1, task : 1, watermark : 1, precise_ip : 2, mmap_data : 1, sample_id_all : 1, exclude_host : 1, exclude_guest : 1, exclude_callchain_kernel : 1, exclude_callchain_user : 1, mmap2 : 1, comm_exec : 1, use_clockid : 1, context_switch : 1, write_backward : 1, __reserved_1 : 36;
+ __u64 disabled : 1, inherit : 1, pinned : 1, exclusive : 1, exclude_user : 1, exclude_kernel : 1, exclude_hv : 1, exclude_idle : 1, mmap : 1, comm : 1, freq : 1, inherit_stat : 1, enable_on_exec : 1, task : 1, watermark : 1, precise_ip : 2, mmap_data : 1, sample_id_all : 1, exclude_host : 1, exclude_guest : 1, exclude_callchain_kernel : 1, exclude_callchain_user : 1, mmap2 : 1, comm_exec : 1, use_clockid : 1, context_switch : 1, write_backward : 1, namespaces : 1, __reserved_1 : 35;
union {
__u32 wakeup_events;
__u32 wakeup_watermark;
@@ -265,6 +265,20 @@
__u16 misc;
__u16 size;
};
+struct perf_ns_link_info {
+ __u64 dev;
+ __u64 ino;
+};
+enum {
+ NET_NS_INDEX = 0,
+ UTS_NS_INDEX = 1,
+ IPC_NS_INDEX = 2,
+ PID_NS_INDEX = 3,
+ USER_NS_INDEX = 4,
+ MNT_NS_INDEX = 5,
+ CGROUP_NS_INDEX = 6,
+ NR_NAMESPACES,
+};
enum perf_event_type {
PERF_RECORD_MMAP = 1,
PERF_RECORD_LOST = 2,
@@ -281,6 +295,7 @@
PERF_RECORD_LOST_SAMPLES = 13,
PERF_RECORD_SWITCH = 14,
PERF_RECORD_SWITCH_CPU_WIDE = 15,
+ PERF_RECORD_NAMESPACES = 16,
PERF_RECORD_MAX,
};
#define PERF_MAX_STACK_DEPTH 127
@@ -296,16 +311,28 @@
};
#define PERF_AUX_FLAG_TRUNCATED 0x01
#define PERF_AUX_FLAG_OVERWRITE 0x02
+#define PERF_AUX_FLAG_PARTIAL 0x04
#define PERF_FLAG_FD_NO_GROUP (1UL << 0)
#define PERF_FLAG_FD_OUTPUT (1UL << 1)
#define PERF_FLAG_PID_CGROUP (1UL << 2)
#define PERF_FLAG_FD_CLOEXEC (1UL << 3)
+#ifdef __LITTLE_ENDIAN_BITFIELD
union perf_mem_data_src {
__u64 val;
struct {
__u64 mem_op : 5, mem_lvl : 14, mem_snoop : 5, mem_lock : 2, mem_dtlb : 7, mem_rsvd : 31;
};
};
+#elif defined(__BIG_ENDIAN_BITFIELD)
+union perf_mem_data_src {
+ __u64 val;
+ struct {
+ __u64 mem_rsvd : 31, mem_dtlb : 7, mem_lock : 2, mem_snoop : 5, mem_lvl : 14, mem_op : 5;
+ };
+};
+#else
+#error "Unknown endianness"
+#endif
#define PERF_MEM_OP_NA 0x01
#define PERF_MEM_OP_LOAD 0x02
#define PERF_MEM_OP_STORE 0x04
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index fb85294..af251c0 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -20,6 +20,7 @@
#define __LINUX_PKT_CLS_H
#include <linux/types.h>
#include <linux/pkt_sched.h>
+#define TC_COOKIE_MAX_SIZE 16
enum {
TCA_ACT_UNSPEC,
TCA_ACT_KIND,
@@ -27,6 +28,7 @@
TCA_ACT_INDEX,
TCA_ACT_STATS,
TCA_ACT_PAD,
+ TCA_ACT_COOKIE,
__TCA_ACT_MAX
};
#define TCA_ACT_MAX __TCA_ACT_MAX
@@ -47,7 +49,11 @@
#define TC_ACT_QUEUED 5
#define TC_ACT_REPEAT 6
#define TC_ACT_REDIRECT 7
-#define TC_ACT_JUMP 0x10000000
+#define __TC_ACT_EXT_SHIFT 28
+#define __TC_ACT_EXT(local) ((local) << __TC_ACT_EXT_SHIFT)
+#define TC_ACT_EXT_VAL_MASK ((1 << __TC_ACT_EXT_SHIFT) - 1)
+#define TC_ACT_EXT_CMP(combined,opcode) (((combined) & (~TC_ACT_EXT_VAL_MASK)) == opcode)
+#define TC_ACT_JUMP __TC_ACT_EXT(1)
enum {
TCA_ID_UNSPEC = 0,
TCA_ID_POLICE = 1,
@@ -97,6 +103,8 @@
#define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1)
#define TCA_CLS_FLAGS_SKIP_HW (1 << 0)
#define TCA_CLS_FLAGS_SKIP_SW (1 << 1)
+#define TCA_CLS_FLAGS_IN_HW (1 << 2)
+#define TCA_CLS_FLAGS_NOT_IN_HW (1 << 3)
#define TC_U32_HTID(h) ((h) & 0xFFF00000)
#define TC_U32_USERHTID(h) (TC_U32_HTID(h) >> 20)
#define TC_U32_HASH(h) (((h) >> 12) & 0xFF)
@@ -344,6 +352,20 @@
TCA_FLOWER_KEY_ICMPV6_CODE_MASK,
TCA_FLOWER_KEY_ICMPV6_TYPE,
TCA_FLOWER_KEY_ICMPV6_TYPE_MASK,
+ TCA_FLOWER_KEY_ARP_SIP,
+ TCA_FLOWER_KEY_ARP_SIP_MASK,
+ TCA_FLOWER_KEY_ARP_TIP,
+ TCA_FLOWER_KEY_ARP_TIP_MASK,
+ TCA_FLOWER_KEY_ARP_OP,
+ TCA_FLOWER_KEY_ARP_OP_MASK,
+ TCA_FLOWER_KEY_ARP_SHA,
+ TCA_FLOWER_KEY_ARP_SHA_MASK,
+ TCA_FLOWER_KEY_ARP_THA,
+ TCA_FLOWER_KEY_ARP_THA_MASK,
+ TCA_FLOWER_KEY_MPLS_TTL,
+ TCA_FLOWER_KEY_MPLS_BOS,
+ TCA_FLOWER_KEY_MPLS_TC,
+ TCA_FLOWER_KEY_MPLS_LABEL,
__TCA_FLOWER_MAX,
};
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index 42cdceb..7d3ff96 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -466,6 +466,12 @@
};
#define TC_QOPT_BITMASK 15
#define TC_QOPT_MAX_QUEUE 16
+enum {
+ TC_MQPRIO_HW_OFFLOAD_NONE,
+ TC_MQPRIO_HW_OFFLOAD_TCS,
+ __TC_MQPRIO_HW_OFFLOAD_MAX
+};
+#define TC_MQPRIO_HW_OFFLOAD_MAX (__TC_MQPRIO_HW_OFFLOAD_MAX - 1)
struct tc_mqprio_qopt {
__u8 num_tc;
__u8 prio_tc_map[TC_QOPT_BITMASK + 1];
diff --git a/libc/kernel/uapi/linux/pps.h b/libc/kernel/uapi/linux/pps.h
index 9db9242..4bfe30d 100644
--- a/libc/kernel/uapi/linux/pps.h
+++ b/libc/kernel/uapi/linux/pps.h
@@ -29,6 +29,11 @@
__s32 nsec;
__u32 flags;
};
+struct pps_ktime_compat {
+ __s64 sec;
+ __s32 nsec;
+ __u32 flags;
+} __attribute__((packed, aligned(4)));
#define PPS_TIME_INVALID (1 << 0)
struct pps_kinfo {
__u32 assert_sequence;
@@ -37,6 +42,13 @@
struct pps_ktime clear_tu;
int current_mode;
};
+struct pps_kinfo_compat {
+ __u32 assert_sequence;
+ __u32 clear_sequence;
+ struct pps_ktime_compat assert_tu;
+ struct pps_ktime_compat clear_tu;
+ int current_mode;
+};
struct pps_kparams {
int api_version;
int mode;
@@ -61,6 +73,10 @@
struct pps_kinfo info;
struct pps_ktime timeout;
};
+struct pps_fdata_compat {
+ struct pps_kinfo_compat info;
+ struct pps_ktime_compat timeout;
+};
struct pps_bind_args {
int tsformat;
int edge;
diff --git a/libc/kernel/uapi/linux/pr.h b/libc/kernel/uapi/linux/pr.h
index 7ce7390..7a7b8b1 100644
--- a/libc/kernel/uapi/linux/pr.h
+++ b/libc/kernel/uapi/linux/pr.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef _UAPI_PR_H
#define _UAPI_PR_H
+#include <linux/types.h>
enum pr_type {
PR_WRITE_EXCLUSIVE = 1,
PR_EXCLUSIVE_ACCESS = 2,
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/psample.h
similarity index 61%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/psample.h
index 3064508..d90956b 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/psample.h
@@ -16,19 +16,28 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
-#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
+#ifndef __UAPI_PSAMPLE_H
+#define __UAPI_PSAMPLE_H
+enum {
+ PSAMPLE_ATTR_IIFINDEX,
+ PSAMPLE_ATTR_OIFINDEX,
+ PSAMPLE_ATTR_ORIGSIZE,
+ PSAMPLE_ATTR_SAMPLE_GROUP,
+ PSAMPLE_ATTR_GROUP_SEQ,
+ PSAMPLE_ATTR_SAMPLE_RATE,
+ PSAMPLE_ATTR_DATA,
+ PSAMPLE_ATTR_GROUP_REFCOUNT,
+ __PSAMPLE_ATTR_MAX
};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+enum psample_command {
+ PSAMPLE_CMD_SAMPLE,
+ PSAMPLE_CMD_GET_GROUP,
+ PSAMPLE_CMD_NEW_GROUP,
+ PSAMPLE_CMD_DEL_GROUP,
+};
+#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1)
+#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config"
+#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets"
+#define PSAMPLE_GENL_NAME "psample"
+#define PSAMPLE_GENL_VERSION 1
#endif
diff --git a/libc/kernel/uapi/linux/qrtr.h b/libc/kernel/uapi/linux/qrtr.h
index bae498f..4040b4c 100644
--- a/libc/kernel/uapi/linux/qrtr.h
+++ b/libc/kernel/uapi/linux/qrtr.h
@@ -19,6 +19,7 @@
#ifndef _LINUX_QRTR_H
#define _LINUX_QRTR_H
#include <linux/socket.h>
+#include <linux/types.h>
struct sockaddr_qrtr {
__kernel_sa_family_t sq_family;
__u32 sq_node;
diff --git a/libc/kernel/uapi/linux/raid/md_p.h b/libc/kernel/uapi/linux/raid/md_p.h
index 661f856..ea54bdb 100644
--- a/libc/kernel/uapi/linux/raid/md_p.h
+++ b/libc/kernel/uapi/linux/raid/md_p.h
@@ -133,7 +133,13 @@
__le64 size;
__le32 chunksize;
__le32 raid_disks;
- __le32 bitmap_offset;
+ union {
+ __le32 bitmap_offset;
+ struct {
+ __le16 offset;
+ __le16 size;
+ } ppl;
+ };
__le32 new_level;
__le64 reshape_position;
__le32 delta_disks;
@@ -174,7 +180,8 @@
#define MD_FEATURE_RECOVERY_BITMAP 128
#define MD_FEATURE_CLUSTERED 256
#define MD_FEATURE_JOURNAL 512
-#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET | MD_FEATURE_RECOVERY_OFFSET | MD_FEATURE_RESHAPE_ACTIVE | MD_FEATURE_BAD_BLOCKS | MD_FEATURE_REPLACEMENT | MD_FEATURE_RESHAPE_BACKWARDS | MD_FEATURE_NEW_OFFSET | MD_FEATURE_RECOVERY_BITMAP | MD_FEATURE_CLUSTERED | MD_FEATURE_JOURNAL)
+#define MD_FEATURE_PPL 1024
+#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET | MD_FEATURE_RECOVERY_OFFSET | MD_FEATURE_RESHAPE_ACTIVE | MD_FEATURE_BAD_BLOCKS | MD_FEATURE_REPLACEMENT | MD_FEATURE_RESHAPE_BACKWARDS | MD_FEATURE_NEW_OFFSET | MD_FEATURE_RECOVERY_BITMAP | MD_FEATURE_CLUSTERED | MD_FEATURE_JOURNAL | MD_FEATURE_PPL)
struct r5l_payload_header {
__le16 type;
__le16 flags;
@@ -216,4 +223,24 @@
} __attribute__((__packed__));
#define R5LOG_VERSION 0x1
#define R5LOG_MAGIC 0x6433c509
+struct ppl_header_entry {
+ __le64 data_sector;
+ __le32 pp_size;
+ __le32 data_size;
+ __le32 parity_disk;
+ __le32 checksum;
+} __attribute__((__packed__));
+#define PPL_HEADER_SIZE 4096
+#define PPL_HDR_RESERVED 512
+#define PPL_HDR_ENTRY_SPACE (PPL_HEADER_SIZE - PPL_HDR_RESERVED - 4 * sizeof(__le32) - sizeof(__le64))
+#define PPL_HDR_MAX_ENTRIES (PPL_HDR_ENTRY_SPACE / sizeof(struct ppl_header_entry))
+struct ppl_header {
+ __u8 reserved[PPL_HDR_RESERVED];
+ __le32 signature;
+ __le32 padding;
+ __le64 generation;
+ __le32 entries_count;
+ __le32 checksum;
+ struct ppl_header_entry entries[PPL_HDR_MAX_ENTRIES];
+} __attribute__((__packed__));
#endif
diff --git a/libc/kernel/uapi/linux/rds.h b/libc/kernel/uapi/linux/rds.h
index eef0d70..ccb3f54 100644
--- a/libc/kernel/uapi/linux/rds.h
+++ b/libc/kernel/uapi/linux/rds.h
@@ -19,6 +19,7 @@
#ifndef _LINUX_RDS_H
#define _LINUX_RDS_H
#include <linux/types.h>
+#include <linux/socket.h>
#define RDS_IB_ABI_VERSION 0x301
#define SOL_RDS 276
#define RDS_CANCEL_SENT_TO 1
@@ -28,6 +29,7 @@
#define RDS_CONG_MONITOR 6
#define RDS_GET_MR_FOR_DEST 7
#define SO_RDS_TRANSPORT 8
+#define SO_RDS_MSG_RXPATH_LATENCY 10
#define RDS_TRANS_IB 0
#define RDS_TRANS_IWARP 1
#define RDS_TRANS_TCP 2
@@ -42,6 +44,7 @@
#define RDS_CMSG_ATOMIC_CSWP 7
#define RDS_CMSG_MASKED_ATOMIC_FADD 8
#define RDS_CMSG_MASKED_ATOMIC_CSWP 9
+#define RDS_CMSG_RXPATH_LATENCY 11
#define RDS_INFO_FIRST 10000
#define RDS_INFO_COUNTERS 10000
#define RDS_INFO_CONNECTIONS 10001
@@ -55,124 +58,139 @@
#define RDS_INFO_IWARP_CONNECTIONS 10010
#define RDS_INFO_LAST 10010
struct rds_info_counter {
- uint8_t name[32];
- uint64_t value;
+ __u8 name[32];
+ __u64 value;
} __attribute__((packed));
#define RDS_INFO_CONNECTION_FLAG_SENDING 0x01
#define RDS_INFO_CONNECTION_FLAG_CONNECTING 0x02
#define RDS_INFO_CONNECTION_FLAG_CONNECTED 0x04
#define TRANSNAMSIZ 16
struct rds_info_connection {
- uint64_t next_tx_seq;
- uint64_t next_rx_seq;
+ __u64 next_tx_seq;
+ __u64 next_rx_seq;
__be32 laddr;
__be32 faddr;
- uint8_t transport[TRANSNAMSIZ];
- uint8_t flags;
+ __u8 transport[TRANSNAMSIZ];
+ __u8 flags;
} __attribute__((packed));
#define RDS_INFO_MESSAGE_FLAG_ACK 0x01
#define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02
struct rds_info_message {
- uint64_t seq;
- uint32_t len;
+ __u64 seq;
+ __u32 len;
__be32 laddr;
__be32 faddr;
__be16 lport;
__be16 fport;
- uint8_t flags;
+ __u8 flags;
} __attribute__((packed));
struct rds_info_socket {
- uint32_t sndbuf;
+ __u32 sndbuf;
__be32 bound_addr;
__be32 connected_addr;
__be16 bound_port;
__be16 connected_port;
- uint32_t rcvbuf;
- uint64_t inum;
+ __u32 rcvbuf;
+ __u64 inum;
} __attribute__((packed));
struct rds_info_tcp_socket {
__be32 local_addr;
__be16 local_port;
__be32 peer_addr;
__be16 peer_port;
- uint64_t hdr_rem;
- uint64_t data_rem;
- uint32_t last_sent_nxt;
- uint32_t last_expected_una;
- uint32_t last_seen_una;
+ __u64 hdr_rem;
+ __u64 data_rem;
+ __u32 last_sent_nxt;
+ __u32 last_expected_una;
+ __u32 last_seen_una;
} __attribute__((packed));
#define RDS_IB_GID_LEN 16
struct rds_info_rdma_connection {
__be32 src_addr;
__be32 dst_addr;
- uint8_t src_gid[RDS_IB_GID_LEN];
- uint8_t dst_gid[RDS_IB_GID_LEN];
- uint32_t max_send_wr;
- uint32_t max_recv_wr;
- uint32_t max_send_sge;
- uint32_t rdma_mr_max;
- uint32_t rdma_mr_size;
+ __u8 src_gid[RDS_IB_GID_LEN];
+ __u8 dst_gid[RDS_IB_GID_LEN];
+ __u32 max_send_wr;
+ __u32 max_recv_wr;
+ __u32 max_send_sge;
+ __u32 rdma_mr_max;
+ __u32 rdma_mr_size;
+};
+enum rds_message_rxpath_latency {
+ RDS_MSG_RX_HDR_TO_DGRAM_START = 0,
+ RDS_MSG_RX_DGRAM_REASSEMBLE,
+ RDS_MSG_RX_DGRAM_DELIVERED,
+ RDS_MSG_RX_DGRAM_TRACE_MAX
+};
+struct rds_rx_trace_so {
+ __u8 rx_traces;
+ __u8 rx_trace_pos[RDS_MSG_RX_DGRAM_TRACE_MAX];
+};
+struct rds_cmsg_rx_trace {
+ __u8 rx_traces;
+ __u8 rx_trace_pos[RDS_MSG_RX_DGRAM_TRACE_MAX];
+ __u64 rx_trace[RDS_MSG_RX_DGRAM_TRACE_MAX];
};
#define RDS_CONG_MONITOR_SIZE 64
#define RDS_CONG_MONITOR_BIT(port) (((unsigned int) port) % RDS_CONG_MONITOR_SIZE)
#define RDS_CONG_MONITOR_MASK(port) (1ULL << RDS_CONG_MONITOR_BIT(port))
-typedef uint64_t rds_rdma_cookie_t;
+typedef __u64 rds_rdma_cookie_t;
struct rds_iovec {
- uint64_t addr;
- uint64_t bytes;
+ __u64 addr;
+ __u64 bytes;
};
struct rds_get_mr_args {
struct rds_iovec vec;
- uint64_t cookie_addr;
- uint64_t flags;
+ __u64 cookie_addr;
+ __u64 flags;
};
struct rds_get_mr_for_dest_args {
- struct sockaddr_storage dest_addr;
+ struct __kernel_sockaddr_storage dest_addr;
struct rds_iovec vec;
- uint64_t cookie_addr;
- uint64_t flags;
+ __u64 cookie_addr;
+ __u64 flags;
};
struct rds_free_mr_args {
rds_rdma_cookie_t cookie;
- uint64_t flags;
+ __u64 flags;
};
struct rds_rdma_args {
rds_rdma_cookie_t cookie;
struct rds_iovec remote_vec;
- uint64_t local_vec_addr;
- uint64_t nr_local;
- uint64_t flags;
- uint64_t user_token;
+ __u64 local_vec_addr;
+ __u64 nr_local;
+ __u64 flags;
+ __u64 user_token;
};
struct rds_atomic_args {
rds_rdma_cookie_t cookie;
- uint64_t local_addr;
- uint64_t remote_addr;
+ __u64 local_addr;
+ __u64 remote_addr;
union {
struct {
- uint64_t compare;
- uint64_t swap;
+ __u64 compare;
+ __u64 swap;
} cswp;
struct {
- uint64_t add;
+ __u64 add;
} fadd;
struct {
- uint64_t compare;
- uint64_t swap;
- uint64_t compare_mask;
- uint64_t swap_mask;
+ __u64 compare;
+ __u64 swap;
+ __u64 compare_mask;
+ __u64 swap_mask;
} m_cswp;
struct {
- uint64_t add;
- uint64_t nocarry_mask;
+ __u64 add;
+ __u64 nocarry_mask;
} m_fadd;
};
- uint64_t flags;
- uint64_t user_token;
+ __u64 flags;
+ __u64 user_token;
};
struct rds_rdma_notify {
- uint64_t user_token;
- int32_t status;
+ __u64 user_token;
+ __s32 status;
};
#define RDS_RDMA_SUCCESS 0
#define RDS_RDMA_REMOTE_ERROR 1
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/rpmsg.h
similarity index 71%
rename from libc/kernel/uapi/linux/ion_test.h
rename to libc/kernel/uapi/linux/rpmsg.h
index 3064508..77f05e6 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/rpmsg.h
@@ -16,19 +16,15 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
+#ifndef _UAPI_RPMSG_H_
+#define _UAPI_RPMSG_H_
#include <linux/ioctl.h>
#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
+struct rpmsg_endpoint_info {
+ char name[32];
+ __u32 src;
+ __u32 dst;
};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+#define RPMSG_CREATE_EPT_IOCTL _IOW(0xb5, 0x1, struct rpmsg_endpoint_info)
+#define RPMSG_DESTROY_EPT_IOCTL _IO(0xb5, 0x2)
#endif
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index 103ff5d..d094068 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -111,6 +111,8 @@
#define RTM_SETDCB RTM_SETDCB
RTM_NEWNETCONF = 80,
#define RTM_NEWNETCONF RTM_NEWNETCONF
+ RTM_DELNETCONF,
+#define RTM_DELNETCONF RTM_DELNETCONF
RTM_GETNETCONF = 82,
#define RTM_GETNETCONF RTM_GETNETCONF
RTM_NEWMDB = 84,
@@ -237,6 +239,7 @@
RTA_EXPIRES,
RTA_PAD,
RTA_UID,
+ RTA_TTL_PROPAGATE,
__RTA_MAX
};
#define RTA_MAX (__RTA_MAX - 1)
@@ -253,6 +256,7 @@
#define RTNH_F_ONLINK 4
#define RTNH_F_OFFLOAD 8
#define RTNH_F_LINKDOWN 16
+#define RTNH_F_UNRESOLVED 32
#define RTNH_COMPARE_MASK (RTNH_F_DEAD | RTNH_F_LINKDOWN | RTNH_F_OFFLOAD)
#define RTNH_ALIGNTO 4
#define RTNH_ALIGN(len) (((len) + RTNH_ALIGNTO - 1) & ~(RTNH_ALIGNTO - 1))
@@ -393,6 +397,7 @@
TCA_STATS2,
TCA_STAB,
TCA_PAD,
+ TCA_DUMP_INVISIBLE,
__TCA_MAX
};
#define TCA_MAX (__TCA_MAX - 1)
@@ -486,6 +491,8 @@
#define RTNLGRP_MPLS_ROUTE RTNLGRP_MPLS_ROUTE
RTNLGRP_NSID,
#define RTNLGRP_NSID RTNLGRP_NSID
+ RTNLGRP_MPLS_NETCONF,
+#define RTNLGRP_MPLS_NETCONF RTNLGRP_MPLS_NETCONF
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/sched/types.h
similarity index 69%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/sched/types.h
index 3064508..cf6f1c7 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/sched/types.h
@@ -16,19 +16,21 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
+#ifndef _UAPI_LINUX_SCHED_TYPES_H
+#define _UAPI_LINUX_SCHED_TYPES_H
#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
+struct sched_param {
+ int sched_priority;
};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+#define SCHED_ATTR_SIZE_VER0 48
+struct sched_attr {
+ __u32 size;
+ __u32 sched_policy;
+ __u64 sched_flags;
+ __s32 sched_nice;
+ __u32 sched_priority;
+ __u64 sched_runtime;
+ __u64 sched_deadline;
+ __u64 sched_period;
+};
#endif
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index ba48874..a5cef43 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -70,6 +70,12 @@
#define SCTP_PR_SUPPORTED 113
#define SCTP_DEFAULT_PRINFO 114
#define SCTP_PR_ASSOC_STATUS 115
+#define SCTP_PR_STREAM_STATUS 116
+#define SCTP_RECONFIG_SUPPORTED 117
+#define SCTP_ENABLE_STREAM_RESET 118
+#define SCTP_RESET_STREAMS 119
+#define SCTP_RESET_ASSOC 120
+#define SCTP_ADD_STREAMS 121
#define SCTP_PR_SCTP_NONE 0x0000
#define SCTP_PR_SCTP_TTL 0x0010
#define SCTP_PR_SCTP_RTX 0x0020
@@ -83,6 +89,12 @@
#define SCTP_PR_TTL_ENABLED(x) (SCTP_PR_POLICY(x) == SCTP_PR_SCTP_TTL)
#define SCTP_PR_RTX_ENABLED(x) (SCTP_PR_POLICY(x) == SCTP_PR_SCTP_RTX)
#define SCTP_PR_PRIO_ENABLED(x) (SCTP_PR_POLICY(x) == SCTP_PR_SCTP_PRIO)
+#define SCTP_ENABLE_RESET_STREAM_REQ 0x01
+#define SCTP_ENABLE_RESET_ASSOC_REQ 0x02
+#define SCTP_ENABLE_CHANGE_ASSOC_REQ 0x04
+#define SCTP_ENABLE_STRRESET_MASK 0x07
+#define SCTP_STREAM_RESET_INCOMING 0x01
+#define SCTP_STREAM_RESET_OUTGOING 0x02
enum sctp_msg_flags {
MSG_NOTIFICATION = 0x8000,
#define MSG_NOTIFICATION MSG_NOTIFICATION
@@ -250,6 +262,37 @@
__u32 sender_dry_length;
sctp_assoc_t sender_dry_assoc_id;
};
+#define SCTP_STREAM_RESET_INCOMING_SSN 0x0001
+#define SCTP_STREAM_RESET_OUTGOING_SSN 0x0002
+#define SCTP_STREAM_RESET_DENIED 0x0004
+#define SCTP_STREAM_RESET_FAILED 0x0008
+struct sctp_stream_reset_event {
+ __u16 strreset_type;
+ __u16 strreset_flags;
+ __u32 strreset_length;
+ sctp_assoc_t strreset_assoc_id;
+ __u16 strreset_stream_list[];
+};
+#define SCTP_ASSOC_RESET_DENIED 0x0004
+#define SCTP_ASSOC_RESET_FAILED 0x0008
+struct sctp_assoc_reset_event {
+ __u16 assocreset_type;
+ __u16 assocreset_flags;
+ __u32 assocreset_length;
+ sctp_assoc_t assocreset_assoc_id;
+ __u32 assocreset_local_tsn;
+ __u32 assocreset_remote_tsn;
+};
+#define SCTP_ASSOC_CHANGE_DENIED 0x0004
+#define SCTP_ASSOC_CHANGE_FAILED 0x0008
+struct sctp_stream_change_event {
+ __u16 strchange_type;
+ __u16 strchange_flags;
+ __u32 strchange_length;
+ sctp_assoc_t strchange_assoc_id;
+ __u16 strchange_instrms;
+ __u16 strchange_outstrms;
+};
struct sctp_event_subscribe {
__u8 sctp_data_io_event;
__u8 sctp_association_event;
@@ -261,6 +304,9 @@
__u8 sctp_adaptation_layer_event;
__u8 sctp_authentication_event;
__u8 sctp_sender_dry_event;
+ __u8 sctp_stream_reset_event;
+ __u8 sctp_assoc_reset_event;
+ __u8 sctp_stream_change_event;
};
union sctp_notification {
struct {
@@ -277,6 +323,9 @@
struct sctp_pdapi_event sn_pdapi_event;
struct sctp_authkey_event sn_authkey_event;
struct sctp_sender_dry_event sn_sender_dry_event;
+ struct sctp_stream_reset_event sn_strreset_event;
+ struct sctp_assoc_reset_event sn_assocreset_event;
+ struct sctp_stream_change_event sn_strchange_event;
};
enum sctp_sn_type {
SCTP_SN_TYPE_BASE = (1 << 15),
@@ -298,6 +347,12 @@
#define SCTP_AUTHENTICATION_INDICATION SCTP_AUTHENTICATION_EVENT
SCTP_SENDER_DRY_EVENT,
#define SCTP_SENDER_DRY_EVENT SCTP_SENDER_DRY_EVENT
+ SCTP_STREAM_RESET_EVENT,
+#define SCTP_STREAM_RESET_EVENT SCTP_STREAM_RESET_EVENT
+ SCTP_ASSOC_RESET_EVENT,
+#define SCTP_ASSOC_RESET_EVENT SCTP_ASSOC_RESET_EVENT
+ SCTP_STREAM_CHANGE_EVENT,
+#define SCTP_STREAM_CHANGE_EVENT SCTP_STREAM_CHANGE_EVENT
};
typedef enum sctp_sn_error {
SCTP_FAILED_THRESHOLD,
@@ -545,4 +600,15 @@
__u32 sctpi_s_type;
__u32 __reserved3;
};
+struct sctp_reset_streams {
+ sctp_assoc_t srs_assoc_id;
+ uint16_t srs_flags;
+ uint16_t srs_number_streams;
+ uint16_t srs_stream_list[];
+};
+struct sctp_add_streams {
+ sctp_assoc_t sas_assoc_id;
+ uint16_t sas_instrms;
+ uint16_t sas_outstrms;
+};
#endif
diff --git a/libc/kernel/uapi/linux/sed-opal.h b/libc/kernel/uapi/linux/sed-opal.h
new file mode 100644
index 0000000..a532073
--- /dev/null
+++ b/libc/kernel/uapi/linux/sed-opal.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_SED_OPAL_H
+#define _UAPI_SED_OPAL_H
+#include <linux/types.h>
+#define OPAL_KEY_MAX 256
+#define OPAL_MAX_LRS 9
+enum opal_mbr {
+ OPAL_MBR_ENABLE = 0x0,
+ OPAL_MBR_DISABLE = 0x01,
+};
+enum opal_user {
+ OPAL_ADMIN1 = 0x0,
+ OPAL_USER1 = 0x01,
+ OPAL_USER2 = 0x02,
+ OPAL_USER3 = 0x03,
+ OPAL_USER4 = 0x04,
+ OPAL_USER5 = 0x05,
+ OPAL_USER6 = 0x06,
+ OPAL_USER7 = 0x07,
+ OPAL_USER8 = 0x08,
+ OPAL_USER9 = 0x09,
+};
+enum opal_lock_state {
+ OPAL_RO = 0x01,
+ OPAL_RW = 0x02,
+ OPAL_LK = 0x04,
+};
+struct opal_key {
+ __u8 lr;
+ __u8 key_len;
+ __u8 __align[6];
+ __u8 key[OPAL_KEY_MAX];
+};
+struct opal_lr_act {
+ struct opal_key key;
+ __u32 sum;
+ __u8 num_lrs;
+ __u8 lr[OPAL_MAX_LRS];
+ __u8 align[2];
+};
+struct opal_session_info {
+ __u32 sum;
+ __u32 who;
+ struct opal_key opal_key;
+};
+struct opal_user_lr_setup {
+ __u64 range_start;
+ __u64 range_length;
+ __u32 RLE;
+ __u32 WLE;
+ struct opal_session_info session;
+};
+struct opal_lock_unlock {
+ struct opal_session_info session;
+ __u32 l_state;
+ __u8 __align[4];
+};
+struct opal_new_pw {
+ struct opal_session_info session;
+ struct opal_session_info new_user_pw;
+};
+struct opal_mbr_data {
+ struct opal_key key;
+ __u8 enable_disable;
+ __u8 __align[7];
+};
+#define IOC_OPAL_SAVE _IOW('p', 220, struct opal_lock_unlock)
+#define IOC_OPAL_LOCK_UNLOCK _IOW('p', 221, struct opal_lock_unlock)
+#define IOC_OPAL_TAKE_OWNERSHIP _IOW('p', 222, struct opal_key)
+#define IOC_OPAL_ACTIVATE_LSP _IOW('p', 223, struct opal_lr_act)
+#define IOC_OPAL_SET_PW _IOW('p', 224, struct opal_new_pw)
+#define IOC_OPAL_ACTIVATE_USR _IOW('p', 225, struct opal_session_info)
+#define IOC_OPAL_REVERT_TPR _IOW('p', 226, struct opal_key)
+#define IOC_OPAL_LR_SETUP _IOW('p', 227, struct opal_user_lr_setup)
+#define IOC_OPAL_ADD_USR_TO_LR _IOW('p', 228, struct opal_lock_unlock)
+#define IOC_OPAL_ENABLE_DISABLE_MBR _IOW('p', 229, struct opal_mbr_data)
+#define IOC_OPAL_ERASE_LR _IOW('p', 230, struct opal_session_info)
+#define IOC_OPAL_SECURE_ERASE_LR _IOW('p', 231, struct opal_session_info)
+#endif
diff --git a/libc/kernel/uapi/linux/seg6.h b/libc/kernel/uapi/linux/seg6.h
index 43a1c3b..6f7b8dd 100644
--- a/libc/kernel/uapi/linux/seg6.h
+++ b/libc/kernel/uapi/linux/seg6.h
@@ -18,6 +18,8 @@
****************************************************************************/
#ifndef _UAPI_LINUX_SEG6_H
#define _UAPI_LINUX_SEG6_H
+#include <linux/types.h>
+#include <linux/in6.h>
struct ipv6_sr_hdr {
__u8 nexthdr;
__u8 hdrlen;
diff --git a/libc/kernel/uapi/linux/seg6_hmac.h b/libc/kernel/uapi/linux/seg6_hmac.h
index 14a838b..d5ef671 100644
--- a/libc/kernel/uapi/linux/seg6_hmac.h
+++ b/libc/kernel/uapi/linux/seg6_hmac.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef _UAPI_LINUX_SEG6_HMAC_H
#define _UAPI_LINUX_SEG6_HMAC_H
+#include <linux/types.h>
#include <linux/seg6.h>
#define SEG6_HMAC_SECRET_LEN 64
#define SEG6_HMAC_FIELD_LEN 32
diff --git a/libc/kernel/uapi/linux/seg6_iptunnel.h b/libc/kernel/uapi/linux/seg6_iptunnel.h
index fdd4705..747fa09 100644
--- a/libc/kernel/uapi/linux/seg6_iptunnel.h
+++ b/libc/kernel/uapi/linux/seg6_iptunnel.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef _UAPI_LINUX_SEG6_IPTUNNEL_H
#define _UAPI_LINUX_SEG6_IPTUNNEL_H
+#include <linux/seg6.h>
enum {
SEG6_IPTUNNEL_UNSPEC,
SEG6_IPTUNNEL_SRH,
diff --git a/libc/kernel/uapi/linux/serial_core.h b/libc/kernel/uapi/linux/serial_core.h
index f51ee71..af349c2 100644
--- a/libc/kernel/uapi/linux/serial_core.h
+++ b/libc/kernel/uapi/linux/serial_core.h
@@ -50,7 +50,8 @@
#define PORT_ALTR_16550_F128 28
#define PORT_RT2880 29
#define PORT_16550A_FSL64 30
-#define PORT_MAX_8250 30
+#define PORT_DA830 31
+#define PORT_MAX_8250 31
#define PORT_PXA 31
#define PORT_AMBA 32
#define PORT_CLPS711X 33
diff --git a/libc/kernel/uapi/linux/serial_reg.h b/libc/kernel/uapi/linux/serial_reg.h
index 7bb7414..95c9956 100644
--- a/libc/kernel/uapi/linux/serial_reg.h
+++ b/libc/kernel/uapi/linux/serial_reg.h
@@ -213,6 +213,10 @@
#define UART_RSA_TCR_SWITCH (1 << 0)
#define SERIAL_RSA_BAUD_BASE (921600)
#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8)
+#define UART_DA830_PWREMU_MGMT 12
+#define UART_DA830_PWREMU_MGMT_FREE (1 << 0)
+#define UART_DA830_PWREMU_MGMT_URRST (1 << 13)
+#define UART_DA830_PWREMU_MGMT_UTRST (1 << 14)
#define OMAP1_UART1_BASE 0xfffb0000
#define OMAP1_UART2_BASE 0xfffb0800
#define OMAP1_UART3_BASE 0xfffb9800
@@ -235,18 +239,6 @@
#define UART_OMAP_MDR1_FIR_MODE 0x05
#define UART_OMAP_MDR1_CIR_MODE 0x06
#define UART_OMAP_MDR1_DISABLE 0x07
-#define UART_EXAR_8XMODE 0x88
-#define UART_EXAR_SLEEP 0x8b
-#define UART_EXAR_DVID 0x8d
-#define UART_EXAR_FCTR 0x08
-#define UART_FCTR_EXAR_IRDA 0x08
-#define UART_FCTR_EXAR_485 0x10
-#define UART_FCTR_EXAR_TRGA 0x00
-#define UART_FCTR_EXAR_TRGB 0x60
-#define UART_FCTR_EXAR_TRGC 0x80
-#define UART_FCTR_EXAR_TRGD 0xc0
-#define UART_EXAR_TXTRG 0x0a
-#define UART_EXAR_RXTRG 0x0b
#define UART_ALTR_AFR 0x40
#define UART_ALTR_EN_TXFIFO_LW 0x01
#define UART_ALTR_TX_LOW 0x41
diff --git a/libc/kernel/uapi/linux/serio.h b/libc/kernel/uapi/linux/serio.h
index 2544d0a..72149ee 100644
--- a/libc/kernel/uapi/linux/serio.h
+++ b/libc/kernel/uapi/linux/serio.h
@@ -20,9 +20,10 @@
#define _UAPI_SERIO_H
#include <linux/ioctl.h>
#define SPIOCSTYPE _IOW('q', 0x01, unsigned long)
-#define SERIO_TIMEOUT 1
-#define SERIO_PARITY 2
-#define SERIO_FRAME 4
+#define SERIO_TIMEOUT BIT(0)
+#define SERIO_PARITY BIT(1)
+#define SERIO_FRAME BIT(2)
+#define SERIO_OOB_DATA BIT(3)
#define SERIO_XT 0x00
#define SERIO_8042 0x01
#define SERIO_RS232 0x02
@@ -74,4 +75,5 @@
#define SERIO_WACOM_IV 0x3e
#define SERIO_EGALAX 0x3f
#define SERIO_PULSE8_CEC 0x40
+#define SERIO_RAINSHADOW_CEC 0x41
#endif
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/smc.h
similarity index 68%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/smc.h
index 3064508..824a29d 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/smc.h
@@ -16,19 +16,23 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
-#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
+#ifndef _UAPI_LINUX_SMC_H_
+#define _UAPI_LINUX_SMC_H_
+enum {
+ SMC_PNETID_UNSPEC,
+ SMC_PNETID_NAME,
+ SMC_PNETID_ETHNAME,
+ SMC_PNETID_IBNAME,
+ SMC_PNETID_IBPORT,
+ __SMC_PNETID_MAX,
+ SMC_PNETID_MAX = __SMC_PNETID_MAX - 1
};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+enum {
+ SMC_PNETID_GET = 1,
+ SMC_PNETID_ADD,
+ SMC_PNETID_DEL,
+ SMC_PNETID_FLUSH
+};
+#define SMCR_GENL_FAMILY_NAME "SMC_PNETID"
+#define SMCR_GENL_FAMILY_VERSION 1
#endif
diff --git a/libc/kernel/uapi/linux/smc_diag.h b/libc/kernel/uapi/linux/smc_diag.h
new file mode 100644
index 0000000..66f93f0
--- /dev/null
+++ b/libc/kernel/uapi/linux/smc_diag.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_SMC_DIAG_H_
+#define _UAPI_SMC_DIAG_H_
+#include <linux/types.h>
+#include <linux/inet_diag.h>
+#include <rdma/ib_user_verbs.h>
+struct smc_diag_req {
+ __u8 diag_family;
+ __u8 pad[2];
+ __u8 diag_ext;
+ struct inet_diag_sockid id;
+};
+struct smc_diag_msg {
+ __u8 diag_family;
+ __u8 diag_state;
+ __u8 diag_fallback;
+ __u8 diag_shutdown;
+ struct inet_diag_sockid id;
+ __u32 diag_uid;
+ __u64 diag_inode;
+};
+enum {
+ SMC_DIAG_NONE,
+ SMC_DIAG_CONNINFO,
+ SMC_DIAG_LGRINFO,
+ SMC_DIAG_SHUTDOWN,
+ __SMC_DIAG_MAX,
+};
+#define SMC_DIAG_MAX (__SMC_DIAG_MAX - 1)
+struct smc_diag_cursor {
+ __u16 reserved;
+ __u16 wrap;
+ __u32 count;
+};
+struct smc_diag_conninfo {
+ __u32 token;
+ __u32 sndbuf_size;
+ __u32 rmbe_size;
+ __u32 peer_rmbe_size;
+ struct smc_diag_cursor rx_prod;
+ struct smc_diag_cursor rx_cons;
+ struct smc_diag_cursor tx_prod;
+ struct smc_diag_cursor tx_cons;
+ __u8 rx_prod_flags;
+ __u8 rx_conn_state_flags;
+ __u8 tx_prod_flags;
+ __u8 tx_conn_state_flags;
+ struct smc_diag_cursor tx_prep;
+ struct smc_diag_cursor tx_sent;
+ struct smc_diag_cursor tx_fin;
+};
+struct smc_diag_linkinfo {
+ __u8 link_id;
+ __u8 ibname[IB_DEVICE_NAME_MAX];
+ __u8 ibport;
+ __u8 gid[40];
+ __u8 peer_gid[40];
+};
+struct smc_diag_lgrinfo {
+ struct smc_diag_linkinfo lnk[1];
+ __u8 role;
+};
+#endif
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index 04a4603..91d693f 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -145,7 +145,6 @@
LINUX_MIB_TIMEWAITED,
LINUX_MIB_TIMEWAITRECYCLED,
LINUX_MIB_TIMEWAITKILLED,
- LINUX_MIB_PAWSPASSIVEREJECTED,
LINUX_MIB_PAWSACTIVEREJECTED,
LINUX_MIB_PAWSESTABREJECTED,
LINUX_MIB_DELAYEDACKS,
@@ -208,6 +207,7 @@
LINUX_MIB_SACKMERGED,
LINUX_MIB_SACKSHIFTFALLBACK,
LINUX_MIB_TCPBACKLOGDROP,
+ LINUX_MIB_PFMEMALLOCDROP,
LINUX_MIB_TCPMINTTLDROP,
LINUX_MIB_TCPDEFERACCEPTDROP,
LINUX_MIB_IPRPFILTER,
@@ -227,6 +227,7 @@
LINUX_MIB_TCPFASTOPENPASSIVEFAIL,
LINUX_MIB_TCPFASTOPENLISTENOVERFLOW,
LINUX_MIB_TCPFASTOPENCOOKIEREQD,
+ LINUX_MIB_TCPFASTOPENBLACKHOLE,
LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES,
LINUX_MIB_BUSYPOLLRXPACKETS,
LINUX_MIB_TCPAUTOCORKING,
diff --git a/libc/kernel/uapi/linux/stat.h b/libc/kernel/uapi/linux/stat.h
index d81758a..bf728d0 100644
--- a/libc/kernel/uapi/linux/stat.h
+++ b/libc/kernel/uapi/linux/stat.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef _UAPI_LINUX_STAT_H
#define _UAPI_LINUX_STAT_H
+#include <linux/types.h>
#if !defined(__GLIBC__) || __GLIBC__ < 2
#define S_IFMT 00170000
#define S_IFSOCK 0140000
@@ -50,4 +51,53 @@
#define S_IWOTH 00002
#define S_IXOTH 00001
#endif
+struct statx_timestamp {
+ __s64 tv_sec;
+ __u32 tv_nsec;
+ __s32 __reserved;
+};
+struct statx {
+ __u32 stx_mask;
+ __u32 stx_blksize;
+ __u64 stx_attributes;
+ __u32 stx_nlink;
+ __u32 stx_uid;
+ __u32 stx_gid;
+ __u16 stx_mode;
+ __u16 __spare0[1];
+ __u64 stx_ino;
+ __u64 stx_size;
+ __u64 stx_blocks;
+ __u64 stx_attributes_mask;
+ struct statx_timestamp stx_atime;
+ struct statx_timestamp stx_btime;
+ struct statx_timestamp stx_ctime;
+ struct statx_timestamp stx_mtime;
+ __u32 stx_rdev_major;
+ __u32 stx_rdev_minor;
+ __u32 stx_dev_major;
+ __u32 stx_dev_minor;
+ __u64 __spare2[14];
+};
+#define STATX_TYPE 0x00000001U
+#define STATX_MODE 0x00000002U
+#define STATX_NLINK 0x00000004U
+#define STATX_UID 0x00000008U
+#define STATX_GID 0x00000010U
+#define STATX_ATIME 0x00000020U
+#define STATX_MTIME 0x00000040U
+#define STATX_CTIME 0x00000080U
+#define STATX_INO 0x00000100U
+#define STATX_SIZE 0x00000200U
+#define STATX_BLOCKS 0x00000400U
+#define STATX_BASIC_STATS 0x000007ffU
+#define STATX_BTIME 0x00000800U
+#define STATX_ALL 0x00000fffU
+#define STATX__RESERVED 0x80000000U
+#define STATX_ATTR_COMPRESSED 0x00000004
+#define STATX_ATTR_IMMUTABLE 0x00000010
+#define STATX_ATTR_APPEND 0x00000020
+#define STATX_ATTR_NODUMP 0x00000040
+#define STATX_ATTR_ENCRYPTED 0x00000800
+#define STATX_ATTR_AUTOMOUNT 0x00001000
#endif
diff --git a/libc/kernel/uapi/linux/switchtec_ioctl.h b/libc/kernel/uapi/linux/switchtec_ioctl.h
new file mode 100644
index 0000000..a0341a8
--- /dev/null
+++ b/libc/kernel/uapi/linux/switchtec_ioctl.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_SWITCHTEC_IOCTL_H
+#define _UAPI_LINUX_SWITCHTEC_IOCTL_H
+#include <linux/types.h>
+#define SWITCHTEC_IOCTL_PART_CFG0 0
+#define SWITCHTEC_IOCTL_PART_CFG1 1
+#define SWITCHTEC_IOCTL_PART_IMG0 2
+#define SWITCHTEC_IOCTL_PART_IMG1 3
+#define SWITCHTEC_IOCTL_PART_NVLOG 4
+#define SWITCHTEC_IOCTL_PART_VENDOR0 5
+#define SWITCHTEC_IOCTL_PART_VENDOR1 6
+#define SWITCHTEC_IOCTL_PART_VENDOR2 7
+#define SWITCHTEC_IOCTL_PART_VENDOR3 8
+#define SWITCHTEC_IOCTL_PART_VENDOR4 9
+#define SWITCHTEC_IOCTL_PART_VENDOR5 10
+#define SWITCHTEC_IOCTL_PART_VENDOR6 11
+#define SWITCHTEC_IOCTL_PART_VENDOR7 12
+#define SWITCHTEC_IOCTL_NUM_PARTITIONS 13
+struct switchtec_ioctl_flash_info {
+ __u64 flash_length;
+ __u32 num_partitions;
+ __u32 padding;
+};
+struct switchtec_ioctl_flash_part_info {
+ __u32 flash_partition;
+ __u32 address;
+ __u32 length;
+ __u32 active;
+};
+struct switchtec_ioctl_event_summary {
+ __u64 global;
+ __u64 part_bitmap;
+ __u32 local_part;
+ __u32 padding;
+ __u32 part[48];
+ __u32 pff[48];
+};
+#define SWITCHTEC_IOCTL_EVENT_STACK_ERROR 0
+#define SWITCHTEC_IOCTL_EVENT_PPU_ERROR 1
+#define SWITCHTEC_IOCTL_EVENT_ISP_ERROR 2
+#define SWITCHTEC_IOCTL_EVENT_SYS_RESET 3
+#define SWITCHTEC_IOCTL_EVENT_FW_EXC 4
+#define SWITCHTEC_IOCTL_EVENT_FW_NMI 5
+#define SWITCHTEC_IOCTL_EVENT_FW_NON_FATAL 6
+#define SWITCHTEC_IOCTL_EVENT_FW_FATAL 7
+#define SWITCHTEC_IOCTL_EVENT_TWI_MRPC_COMP 8
+#define SWITCHTEC_IOCTL_EVENT_TWI_MRPC_COMP_ASYNC 9
+#define SWITCHTEC_IOCTL_EVENT_CLI_MRPC_COMP 10
+#define SWITCHTEC_IOCTL_EVENT_CLI_MRPC_COMP_ASYNC 11
+#define SWITCHTEC_IOCTL_EVENT_GPIO_INT 12
+#define SWITCHTEC_IOCTL_EVENT_PART_RESET 13
+#define SWITCHTEC_IOCTL_EVENT_MRPC_COMP 14
+#define SWITCHTEC_IOCTL_EVENT_MRPC_COMP_ASYNC 15
+#define SWITCHTEC_IOCTL_EVENT_DYN_PART_BIND_COMP 16
+#define SWITCHTEC_IOCTL_EVENT_AER_IN_P2P 17
+#define SWITCHTEC_IOCTL_EVENT_AER_IN_VEP 18
+#define SWITCHTEC_IOCTL_EVENT_DPC 19
+#define SWITCHTEC_IOCTL_EVENT_CTS 20
+#define SWITCHTEC_IOCTL_EVENT_HOTPLUG 21
+#define SWITCHTEC_IOCTL_EVENT_IER 22
+#define SWITCHTEC_IOCTL_EVENT_THRESH 23
+#define SWITCHTEC_IOCTL_EVENT_POWER_MGMT 24
+#define SWITCHTEC_IOCTL_EVENT_TLP_THROTTLING 25
+#define SWITCHTEC_IOCTL_EVENT_FORCE_SPEED 26
+#define SWITCHTEC_IOCTL_EVENT_CREDIT_TIMEOUT 27
+#define SWITCHTEC_IOCTL_EVENT_LINK_STATE 28
+#define SWITCHTEC_IOCTL_MAX_EVENTS 29
+#define SWITCHTEC_IOCTL_EVENT_LOCAL_PART_IDX - 1
+#define SWITCHTEC_IOCTL_EVENT_IDX_ALL - 2
+#define SWITCHTEC_IOCTL_EVENT_FLAG_CLEAR (1 << 0)
+#define SWITCHTEC_IOCTL_EVENT_FLAG_EN_POLL (1 << 1)
+#define SWITCHTEC_IOCTL_EVENT_FLAG_EN_LOG (1 << 2)
+#define SWITCHTEC_IOCTL_EVENT_FLAG_EN_CLI (1 << 3)
+#define SWITCHTEC_IOCTL_EVENT_FLAG_EN_FATAL (1 << 4)
+#define SWITCHTEC_IOCTL_EVENT_FLAG_DIS_POLL (1 << 5)
+#define SWITCHTEC_IOCTL_EVENT_FLAG_DIS_LOG (1 << 6)
+#define SWITCHTEC_IOCTL_EVENT_FLAG_DIS_CLI (1 << 7)
+#define SWITCHTEC_IOCTL_EVENT_FLAG_DIS_FATAL (1 << 8)
+#define SWITCHTEC_IOCTL_EVENT_FLAG_UNUSED (~0x1ff)
+struct switchtec_ioctl_event_ctl {
+ __u32 event_id;
+ __s32 index;
+ __u32 flags;
+ __u32 occurred;
+ __u32 count;
+ __u32 data[5];
+};
+#define SWITCHTEC_IOCTL_PFF_VEP 100
+struct switchtec_ioctl_pff_port {
+ __u32 pff;
+ __u32 partition;
+ __u32 port;
+};
+#define SWITCHTEC_IOCTL_FLASH_INFO _IOR('W', 0x40, struct switchtec_ioctl_flash_info)
+#define SWITCHTEC_IOCTL_FLASH_PART_INFO _IOWR('W', 0x41, struct switchtec_ioctl_flash_part_info)
+#define SWITCHTEC_IOCTL_EVENT_SUMMARY _IOR('W', 0x42, struct switchtec_ioctl_event_summary)
+#define SWITCHTEC_IOCTL_EVENT_CTL _IOWR('W', 0x43, struct switchtec_ioctl_event_ctl)
+#define SWITCHTEC_IOCTL_PFF_TO_PORT _IOWR('W', 0x44, struct switchtec_ioctl_pff_port)
+#define SWITCHTEC_IOCTL_PORT_TO_PFF _IOWR('W', 0x45, struct switchtec_ioctl_pff_port)
+#endif
diff --git a/libc/kernel/uapi/linux/sysctl.h b/libc/kernel/uapi/linux/sysctl.h
index 5389d61..47c39fc 100644
--- a/libc/kernel/uapi/linux/sysctl.h
+++ b/libc/kernel/uapi/linux/sysctl.h
@@ -487,6 +487,7 @@
NET_IPV6_PROXY_NDP = 23,
NET_IPV6_ACCEPT_SOURCE_ROUTE = 25,
NET_IPV6_ACCEPT_RA_FROM_LOCAL = 26,
+ NET_IPV6_ACCEPT_RA_RT_INFO_MIN_PLEN = 27,
__NET_IPV6_MAX
};
enum {
diff --git a/libc/kernel/uapi/linux/target_core_user.h b/libc/kernel/uapi/linux/target_core_user.h
index 8af4766..640e9c7 100644
--- a/libc/kernel/uapi/linux/target_core_user.h
+++ b/libc/kernel/uapi/linux/target_core_user.h
@@ -49,24 +49,24 @@
struct tcmu_cmd_entry_hdr hdr;
union {
struct {
- uint32_t iov_cnt;
- uint32_t iov_bidi_cnt;
- uint32_t iov_dif_cnt;
- uint64_t cdb_off;
- uint64_t __pad1;
- uint64_t __pad2;
+ __u32 iov_cnt;
+ __u32 iov_bidi_cnt;
+ __u32 iov_dif_cnt;
+ __u64 cdb_off;
+ __u64 __pad1;
+ __u64 __pad2;
struct iovec iov[0];
} req;
struct {
- uint8_t scsi_status;
- uint8_t __pad1;
- uint16_t __pad2;
- uint32_t __pad3;
+ __u8 scsi_status;
+ __u8 __pad1;
+ __u16 __pad2;
+ __u32 __pad3;
char sense_buffer[TCMU_SENSE_BUFFERSIZE];
} rsp;
};
} __packed;
-#define TCMU_OP_ALIGN_SIZE sizeof(uint64_t)
+#define TCMU_OP_ALIGN_SIZE sizeof(__u64)
enum tcmu_genl_cmd {
TCMU_CMD_UNSPEC,
TCMU_CMD_ADDED_DEVICE,
diff --git a/libc/kernel/uapi/linux/tc_act/tc_csum.h b/libc/kernel/uapi/linux/tc_act/tc_csum.h
index 5771b29..7de4019 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_csum.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_csum.h
@@ -35,7 +35,8 @@
TCA_CSUM_UPDATE_FLAG_IGMP = 4,
TCA_CSUM_UPDATE_FLAG_TCP = 8,
TCA_CSUM_UPDATE_FLAG_UDP = 16,
- TCA_CSUM_UPDATE_FLAG_UDPLITE = 32
+ TCA_CSUM_UPDATE_FLAG_UDPLITE = 32,
+ TCA_CSUM_UPDATE_FLAG_SCTP = 64,
};
struct tc_csum {
tc_gen;
diff --git a/libc/kernel/uapi/linux/tc_act/tc_ife.h b/libc/kernel/uapi/linux/tc_act/tc_ife.h
index 1079d9d..3193be0 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_ife.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_ife.h
@@ -20,6 +20,7 @@
#define __UAPI_TC_IFE_H
#include <linux/types.h>
#include <linux/pkt_cls.h>
+#include <linux/ife.h>
#define TCA_ACT_IFE 25
#define IFE_ENCODE 1
#define IFE_DECODE 0
@@ -39,11 +40,4 @@
__TCA_IFE_MAX
};
#define TCA_IFE_MAX (__TCA_IFE_MAX - 1)
-#define IFE_META_SKBMARK 1
-#define IFE_META_HASHID 2
-#define IFE_META_PRIO 3
-#define IFE_META_QMAP 4
-#define IFE_META_TCINDEX 5
-#define __IFE_META_MAX 6
-#define IFE_META_MAX (__IFE_META_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/tc_act/tc_pedit.h b/libc/kernel/uapi/linux/tc_act/tc_pedit.h
index 02c9fdb..93eb1dc 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_pedit.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_pedit.h
@@ -26,9 +26,34 @@
TCA_PEDIT_TM,
TCA_PEDIT_PARMS,
TCA_PEDIT_PAD,
+ TCA_PEDIT_PARMS_EX,
+ TCA_PEDIT_KEYS_EX,
+ TCA_PEDIT_KEY_EX,
__TCA_PEDIT_MAX
};
#define TCA_PEDIT_MAX (__TCA_PEDIT_MAX - 1)
+enum {
+ TCA_PEDIT_KEY_EX_HTYPE = 1,
+ TCA_PEDIT_KEY_EX_CMD = 2,
+ __TCA_PEDIT_KEY_EX_MAX
+};
+#define TCA_PEDIT_KEY_EX_MAX (__TCA_PEDIT_KEY_EX_MAX - 1)
+enum pedit_header_type {
+ TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK = 0,
+ TCA_PEDIT_KEY_EX_HDR_TYPE_ETH = 1,
+ TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 = 2,
+ TCA_PEDIT_KEY_EX_HDR_TYPE_IP6 = 3,
+ TCA_PEDIT_KEY_EX_HDR_TYPE_TCP = 4,
+ TCA_PEDIT_KEY_EX_HDR_TYPE_UDP = 5,
+ __PEDIT_HDR_TYPE_MAX,
+};
+#define TCA_PEDIT_HDR_TYPE_MAX (__PEDIT_HDR_TYPE_MAX - 1)
+enum pedit_cmd {
+ TCA_PEDIT_KEY_EX_CMD_SET = 0,
+ TCA_PEDIT_KEY_EX_CMD_ADD = 1,
+ __PEDIT_CMD_MAX,
+};
+#define TCA_PEDIT_CMD_MAX (__PEDIT_CMD_MAX - 1)
struct tc_pedit_key {
__u32 mask;
__u32 val;
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/tc_act/tc_sample.h
similarity index 69%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/tc_act/tc_sample.h
index 3064508..64f5d08 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_sample.h
@@ -16,19 +16,24 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
+#ifndef __LINUX_TC_SAMPLE_H
+#define __LINUX_TC_SAMPLE_H
#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
+#include <linux/pkt_cls.h>
+#include <linux/if_ether.h>
+#define TCA_ACT_SAMPLE 26
+struct tc_sample {
+ tc_gen;
};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+enum {
+ TCA_SAMPLE_UNSPEC,
+ TCA_SAMPLE_TM,
+ TCA_SAMPLE_PARMS,
+ TCA_SAMPLE_RATE,
+ TCA_SAMPLE_TRUNC_SIZE,
+ TCA_SAMPLE_PSAMPLE_GROUP,
+ TCA_SAMPLE_PAD,
+ __TCA_SAMPLE_MAX
+};
+#define TCA_SAMPLE_MAX (__TCA_SAMPLE_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index c388761..9c3a90d 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -84,6 +84,7 @@
#define TCP_SAVE_SYN 27
#define TCP_SAVED_SYN 28
#define TCP_REPAIR_WINDOW 29
+#define TCP_FASTOPEN_CONNECT 30
struct tcp_repair_opt {
__u32 opt_code;
__u32 opt_val;
@@ -172,6 +173,8 @@
TCP_NLA_BUSY,
TCP_NLA_RWND_LIMITED,
TCP_NLA_SNDBUF_LIMITED,
+ TCP_NLA_DATA_SEGS_OUT,
+ TCP_NLA_TOTAL_RETRANS,
};
#define TCP_MD5SIG_MAXKEYLEN 80
struct tcp_md5sig {
diff --git a/libc/kernel/uapi/linux/tee.h b/libc/kernel/uapi/linux/tee.h
new file mode 100644
index 0000000..9a42337
--- /dev/null
+++ b/libc/kernel/uapi/linux/tee.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 __TEE_H
+#define __TEE_H
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define TEE_IOC_MAGIC 0xa4
+#define TEE_IOC_BASE 0
+#define TEE_IOCTL_SHM_MAPPED 0x1
+#define TEE_IOCTL_SHM_DMA_BUF 0x2
+#define TEE_MAX_ARG_SIZE 1024
+#define TEE_GEN_CAP_GP (1 << 0)
+#define TEE_IMPL_ID_OPTEE 1
+#define TEE_OPTEE_CAP_TZ (1 << 0)
+struct tee_ioctl_version_data {
+ __u32 impl_id;
+ __u32 impl_caps;
+ __u32 gen_caps;
+};
+#define TEE_IOC_VERSION _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 0, struct tee_ioctl_version_data)
+struct tee_ioctl_shm_alloc_data {
+ __u64 size;
+ __u32 flags;
+ __s32 id;
+};
+#define TEE_IOC_SHM_ALLOC _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 1, struct tee_ioctl_shm_alloc_data)
+struct tee_ioctl_buf_data {
+ __u64 buf_ptr;
+ __u64 buf_len;
+};
+#define TEE_IOCTL_PARAM_ATTR_TYPE_NONE 0
+#define TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT 1
+#define TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT 2
+#define TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT 3
+#define TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT 5
+#define TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT 6
+#define TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT 7
+#define TEE_IOCTL_PARAM_ATTR_TYPE_MASK 0xff
+#define TEE_IOCTL_LOGIN_PUBLIC 0
+#define TEE_IOCTL_LOGIN_USER 1
+#define TEE_IOCTL_LOGIN_GROUP 2
+#define TEE_IOCTL_LOGIN_APPLICATION 4
+#define TEE_IOCTL_LOGIN_USER_APPLICATION 5
+#define TEE_IOCTL_LOGIN_GROUP_APPLICATION 6
+struct tee_ioctl_param {
+ __u64 attr;
+ __u64 a;
+ __u64 b;
+ __u64 c;
+};
+#define TEE_IOCTL_UUID_LEN 16
+struct tee_ioctl_open_session_arg {
+ __u8 uuid[TEE_IOCTL_UUID_LEN];
+ __u8 clnt_uuid[TEE_IOCTL_UUID_LEN];
+ __u32 clnt_login;
+ __u32 cancel_id;
+ __u32 session;
+ __u32 ret;
+ __u32 ret_origin;
+ __u32 num_params;
+ struct tee_ioctl_param params[];
+};
+#define TEE_IOC_OPEN_SESSION _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 2, struct tee_ioctl_buf_data)
+struct tee_ioctl_invoke_arg {
+ __u32 func;
+ __u32 session;
+ __u32 cancel_id;
+ __u32 ret;
+ __u32 ret_origin;
+ __u32 num_params;
+ struct tee_ioctl_param params[];
+};
+#define TEE_IOC_INVOKE _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 3, struct tee_ioctl_buf_data)
+struct tee_ioctl_cancel_arg {
+ __u32 cancel_id;
+ __u32 session;
+};
+#define TEE_IOC_CANCEL _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 4, struct tee_ioctl_cancel_arg)
+struct tee_ioctl_close_session_arg {
+ __u32 session;
+};
+#define TEE_IOC_CLOSE_SESSION _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 5, struct tee_ioctl_close_session_arg)
+struct tee_iocl_supp_recv_arg {
+ __u32 func;
+ __u32 num_params;
+ struct tee_ioctl_param params[];
+};
+#define TEE_IOC_SUPPL_RECV _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 6, struct tee_ioctl_buf_data)
+struct tee_iocl_supp_send_arg {
+ __u32 ret;
+ __u32 num_params;
+ struct tee_ioctl_param params[];
+};
+#define TEE_IOC_SUPPL_SEND _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 7, struct tee_ioctl_buf_data)
+#endif
diff --git a/libc/kernel/uapi/linux/tipc.h b/libc/kernel/uapi/linux/tipc.h
index a7b18db..cf16725 100644
--- a/libc/kernel/uapi/linux/tipc.h
+++ b/libc/kernel/uapi/linux/tipc.h
@@ -119,6 +119,8 @@
#define TIPC_CONN_TIMEOUT 130
#define TIPC_NODE_RECVQ_DEPTH 131
#define TIPC_SOCK_RECVQ_DEPTH 132
+#define TIPC_MCAST_BROADCAST 133
+#define TIPC_MCAST_REPLICAST 134
#define TIPC_MAX_MEDIA_NAME 16
#define TIPC_MAX_IF_NAME 16
#define TIPC_MAX_BEARER_NAME 32
diff --git a/libc/kernel/uapi/linux/un.h b/libc/kernel/uapi/linux/un.h
index f735c74..fefbf5b 100644
--- a/libc/kernel/uapi/linux/un.h
+++ b/libc/kernel/uapi/linux/un.h
@@ -24,4 +24,5 @@
__kernel_sa_family_t sun_family;
char sun_path[UNIX_PATH_MAX];
};
+#define SIOCUNIXFILE (SIOCPROTOPRIVATE + 0)
#endif
diff --git a/libc/kernel/uapi/linux/usb/ch11.h b/libc/kernel/uapi/linux/usb/ch11.h
index 41fc972..e31c37b 100644
--- a/libc/kernel/uapi/linux/usb/ch11.h
+++ b/libc/kernel/uapi/linux/usb/ch11.h
@@ -20,6 +20,7 @@
#define __LINUX_CH11_H
#include <linux/types.h>
#define USB_MAXCHILDREN 31
+#define USB_SS_MAXPORTS 15
#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
#define HUB_PORT_STATUS 0
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
index 4c4b356..caa1eb4 100644
--- a/libc/kernel/uapi/linux/userfaultfd.h
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -20,9 +20,10 @@
#define _LINUX_USERFAULTFD_H
#include <linux/types.h>
#define UFFD_API ((__u64) 0xAA)
-#define UFFD_API_FEATURES (0)
+#define UFFD_API_FEATURES (UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM)
#define UFFD_API_IOCTLS ((__u64) 1 << _UFFDIO_REGISTER | (__u64) 1 << _UFFDIO_UNREGISTER | (__u64) 1 << _UFFDIO_API)
#define UFFD_API_RANGE_IOCTLS ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_ZEROPAGE)
+#define UFFD_API_RANGE_IOCTLS_BASIC ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY)
#define _UFFDIO_REGISTER (0x00)
#define _UFFDIO_UNREGISTER (0x01)
#define _UFFDIO_WAKE (0x02)
@@ -47,6 +48,18 @@
__u64 address;
} pagefault;
struct {
+ __u32 ufd;
+ } fork;
+ struct {
+ __u64 from;
+ __u64 to;
+ __u64 len;
+ } remap;
+ struct {
+ __u64 start;
+ __u64 end;
+ } remove;
+ struct {
__u64 reserved1;
__u64 reserved2;
__u64 reserved3;
@@ -54,10 +67,21 @@
} arg;
} __packed;
#define UFFD_EVENT_PAGEFAULT 0x12
+#define UFFD_EVENT_FORK 0x13
+#define UFFD_EVENT_REMAP 0x14
+#define UFFD_EVENT_REMOVE 0x15
+#define UFFD_EVENT_UNMAP 0x16
#define UFFD_PAGEFAULT_FLAG_WRITE (1 << 0)
#define UFFD_PAGEFAULT_FLAG_WP (1 << 1)
struct uffdio_api {
__u64 api;
+#define UFFD_FEATURE_PAGEFAULT_FLAG_WP (1 << 0)
+#define UFFD_FEATURE_EVENT_FORK (1 << 1)
+#define UFFD_FEATURE_EVENT_REMAP (1 << 2)
+#define UFFD_FEATURE_EVENT_REMOVE (1 << 3)
+#define UFFD_FEATURE_MISSING_HUGETLBFS (1 << 4)
+#define UFFD_FEATURE_MISSING_SHMEM (1 << 5)
+#define UFFD_FEATURE_EVENT_UNMAP (1 << 6)
__u64 features;
__u64 ioctls;
};
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 8b3dd99..73eb988 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
***
****************************************************************************
****************************************************************************/
-#define LINUX_VERSION_CODE 264704
+#define LINUX_VERSION_CODE 265219
#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 61e8be4..4e3fdb7 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -56,6 +56,7 @@
#define VFIO_DEVICE_FLAGS_PCI (1 << 1)
#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2)
#define VFIO_DEVICE_FLAGS_AMBA (1 << 3)
+#define VFIO_DEVICE_FLAGS_CCW (1 << 4)
__u32 num_regions;
__u32 num_irqs;
};
@@ -63,6 +64,7 @@
#define VFIO_DEVICE_API_PCI_STRING "vfio-pci"
#define VFIO_DEVICE_API_PLATFORM_STRING "vfio-platform"
#define VFIO_DEVICE_API_AMBA_STRING "vfio-amba"
+#define VFIO_DEVICE_API_CCW_STRING "vfio-ccw"
struct vfio_region_info {
__u32 argsz;
__u32 flags;
@@ -147,6 +149,14 @@
VFIO_PCI_REQ_IRQ_INDEX,
VFIO_PCI_NUM_IRQS
};
+enum {
+ VFIO_CCW_CONFIG_REGION_INDEX,
+ VFIO_CCW_NUM_REGIONS
+};
+enum {
+ VFIO_CCW_IO_IRQ_INDEX,
+ VFIO_CCW_NUM_IRQS
+};
struct vfio_pci_dependent_device {
__u32 group_id;
__u16 segment;
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/vfio_ccw.h
similarity index 69%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/vfio_ccw.h
index 3064508..047862f 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/vfio_ccw.h
@@ -16,19 +16,16 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
+#ifndef _VFIO_CCW_H_
+#define _VFIO_CCW_H_
#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
-};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+struct ccw_io_region {
+#define ORB_AREA_SIZE 12
+ __u8 orb_area[ORB_AREA_SIZE];
+#define SCSW_AREA_SIZE 12
+ __u8 scsw_area[SCSW_AREA_SIZE];
+#define IRB_AREA_SIZE 96
+ __u8 irb_area[IRB_AREA_SIZE];
+ __u32 ret_code;
+} __packed;
#endif
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 47b47ae..25e2fe8 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -57,6 +57,7 @@
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
V4L2_BUF_TYPE_SDR_CAPTURE = 11,
V4L2_BUF_TYPE_SDR_OUTPUT = 12,
+ V4L2_BUF_TYPE_META_CAPTURE = 13,
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)
@@ -123,7 +124,7 @@
V4L2_QUANTIZATION_FULL_RANGE = 1,
V4L2_QUANTIZATION_LIM_RANGE = 2,
};
-#define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb_or_hsv,colsp,ycbcr_enc) (((is_rgb_or_hsv) && (colsp) == V4L2_COLORSPACE_BT2020) ? V4L2_QUANTIZATION_LIM_RANGE : (((is_rgb_or_hsv) || (ycbcr_enc) == V4L2_YCBCR_ENC_XV601 || (ycbcr_enc) == V4L2_YCBCR_ENC_XV709 || (colsp) == V4L2_COLORSPACE_JPEG) ? V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE))
+#define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb_or_hsv,colsp,ycbcr_enc) (((is_rgb_or_hsv) && (colsp) == V4L2_COLORSPACE_BT2020) ? V4L2_QUANTIZATION_LIM_RANGE : (((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE))
enum v4l2_priority {
V4L2_PRIORITY_UNSET = 0,
V4L2_PRIORITY_BACKGROUND = 1,
@@ -172,6 +173,7 @@
#define V4L2_CAP_SDR_CAPTURE 0x00100000
#define V4L2_CAP_EXT_PIX_FORMAT 0x00200000
#define V4L2_CAP_SDR_OUTPUT 0x00400000
+#define V4L2_CAP_META_CAPTURE 0x00800000
#define V4L2_CAP_READWRITE 0x01000000
#define V4L2_CAP_ASYNCIO 0x02000000
#define V4L2_CAP_STREAMING 0x04000000
@@ -338,6 +340,7 @@
#define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I')
#define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ')
#define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1')
+#define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I')
#define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8')
#define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6')
#define V4L2_SDR_FMT_CS8 v4l2_fourcc('C', 'S', '0', '8')
@@ -347,6 +350,8 @@
#define V4L2_TCH_FMT_DELTA_TD08 v4l2_fourcc('T', 'D', '0', '8')
#define V4L2_TCH_FMT_TU16 v4l2_fourcc('T', 'U', '1', '6')
#define V4L2_TCH_FMT_TU08 v4l2_fourcc('T', 'U', '0', '8')
+#define V4L2_META_FMT_VSP1_HGO v4l2_fourcc('V', 'S', 'P', 'H')
+#define V4L2_META_FMT_VSP1_HGT v4l2_fourcc('V', 'S', 'P', 'T')
#define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe
#define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA 0x00000001
struct v4l2_fmtdesc {
@@ -865,6 +870,7 @@
#define V4L2_CTRL_FLAG_VOLATILE 0x0080
#define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100
#define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200
+#define V4L2_CTRL_FLAG_MODIFY_LAYOUT 0x0400
#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
#define V4L2_CTRL_FLAG_NEXT_COMPOUND 0x40000000
#define V4L2_CID_MAX_CTRLS 1024
@@ -1128,6 +1134,10 @@
__u32 buffersize;
__u8 reserved[24];
} __attribute__((packed));
+struct v4l2_meta_format {
+ __u32 dataformat;
+ __u32 buffersize;
+} __attribute__((packed));
struct v4l2_format {
__u32 type;
union {
@@ -1137,6 +1147,7 @@
struct v4l2_vbi_format vbi;
struct v4l2_sliced_vbi_format sliced;
struct v4l2_sdr_format sdr;
+ struct v4l2_meta_format meta;
__u8 raw_data[200];
} fmt;
};
diff --git a/libc/kernel/uapi/linux/virtio_mmio.h b/libc/kernel/uapi/linux/virtio_mmio.h
new file mode 100644
index 0000000..a11de1c
--- /dev/null
+++ b/libc/kernel/uapi/linux/virtio_mmio.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_VIRTIO_MMIO_H
+#define _LINUX_VIRTIO_MMIO_H
+#define VIRTIO_MMIO_MAGIC_VALUE 0x000
+#define VIRTIO_MMIO_VERSION 0x004
+#define VIRTIO_MMIO_DEVICE_ID 0x008
+#define VIRTIO_MMIO_VENDOR_ID 0x00c
+#define VIRTIO_MMIO_DEVICE_FEATURES 0x010
+#define VIRTIO_MMIO_DEVICE_FEATURES_SEL 0x014
+#define VIRTIO_MMIO_DRIVER_FEATURES 0x020
+#define VIRTIO_MMIO_DRIVER_FEATURES_SEL 0x024
+#ifndef VIRTIO_MMIO_NO_LEGACY
+#define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028
+#endif
+#define VIRTIO_MMIO_QUEUE_SEL 0x030
+#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034
+#define VIRTIO_MMIO_QUEUE_NUM 0x038
+#ifndef VIRTIO_MMIO_NO_LEGACY
+#define VIRTIO_MMIO_QUEUE_ALIGN 0x03c
+#define VIRTIO_MMIO_QUEUE_PFN 0x040
+#endif
+#define VIRTIO_MMIO_QUEUE_READY 0x044
+#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050
+#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060
+#define VIRTIO_MMIO_INTERRUPT_ACK 0x064
+#define VIRTIO_MMIO_STATUS 0x070
+#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080
+#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084
+#define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090
+#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094
+#define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0
+#define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4
+#define VIRTIO_MMIO_CONFIG_GENERATION 0x0fc
+#define VIRTIO_MMIO_CONFIG 0x100
+#define VIRTIO_MMIO_INT_VRING (1 << 0)
+#define VIRTIO_MMIO_INT_CONFIG (1 << 1)
+#endif
diff --git a/libc/kernel/uapi/linux/ion_test.h b/libc/kernel/uapi/linux/vsockmon.h
similarity index 64%
copy from libc/kernel/uapi/linux/ion_test.h
copy to libc/kernel/uapi/linux/vsockmon.h
index 3064508..6435b5a 100644
--- a/libc/kernel/uapi/linux/ion_test.h
+++ b/libc/kernel/uapi/linux/vsockmon.h
@@ -16,19 +16,29 @@
***
****************************************************************************
****************************************************************************/
-#ifndef _UAPI_LINUX_ION_TEST_H
-#define _UAPI_LINUX_ION_TEST_H
-#include <linux/ioctl.h>
-#include <linux/types.h>
-struct ion_test_rw_data {
- __u64 ptr;
- __u64 offset;
- __u64 size;
- int write;
- int __padding;
+#ifndef _UAPI_VSOCKMON_H
+#define _UAPI_VSOCKMON_H
+#include <linux/virtio_vsock.h>
+struct af_vsockmon_hdr {
+ __le64 src_cid;
+ __le64 dst_cid;
+ __le32 src_port;
+ __le32 dst_port;
+ __le16 op;
+ __le16 transport;
+ __le16 len;
+ __u8 reserved[2];
};
-#define ION_IOC_MAGIC 'I'
-#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
-#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
-#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
+enum af_vsockmon_op {
+ AF_VSOCK_OP_UNKNOWN = 0,
+ AF_VSOCK_OP_CONNECT = 1,
+ AF_VSOCK_OP_DISCONNECT = 2,
+ AF_VSOCK_OP_CONTROL = 3,
+ AF_VSOCK_OP_PAYLOAD = 4,
+};
+enum af_vsockmon_transport {
+ AF_VSOCK_TRANSPORT_UNKNOWN = 0,
+ AF_VSOCK_TRANSPORT_NO_INFO = 1,
+ AF_VSOCK_TRANSPORT_VIRTIO = 2,
+};
#endif
diff --git a/libc/kernel/uapi/linux/xfrm.h b/libc/kernel/uapi/linux/xfrm.h
index 69a8538..4ff9bea 100644
--- a/libc/kernel/uapi/linux/xfrm.h
+++ b/libc/kernel/uapi/linux/xfrm.h
@@ -257,6 +257,7 @@
XFRMA_PROTO,
XFRMA_ADDRESS_FILTER,
XFRMA_PAD,
+ XFRMA_OFFLOAD_DEV,
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
};
@@ -418,6 +419,12 @@
__u8 splen;
__u8 dplen;
};
+struct xfrm_user_offload {
+ int ifindex;
+ __u8 flags;
+};
+#define XFRM_OFFLOAD_IPV6 1
+#define XFRM_OFFLOAD_INBOUND 2
#define XFRMGRP_ACQUIRE 1
#define XFRMGRP_EXPIRE 2
#define XFRMGRP_SA 4
diff --git a/libc/kernel/uapi/rdma/bnxt_re-abi.h b/libc/kernel/uapi/rdma/bnxt_re-abi.h
new file mode 100644
index 0000000..873c466
--- /dev/null
+++ b/libc/kernel/uapi/rdma/bnxt_re-abi.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 __BNXT_RE_UVERBS_ABI_H__
+#define __BNXT_RE_UVERBS_ABI_H__
+#include <linux/types.h>
+#define BNXT_RE_ABI_VERSION 1
+struct bnxt_re_uctx_resp {
+ __u32 dev_id;
+ __u32 max_qp;
+ __u32 pg_size;
+ __u32 cqe_sz;
+ __u32 max_cqd;
+ __u32 rsvd;
+};
+struct bnxt_re_pd_resp {
+ __u32 pdid;
+ __u32 dpi;
+ __u64 dbr;
+};
+struct bnxt_re_cq_req {
+ __u64 cq_va;
+ __u64 cq_handle;
+};
+struct bnxt_re_cq_resp {
+ __u32 cqid;
+ __u32 tail;
+ __u32 phase;
+ __u32 rsvd;
+};
+struct bnxt_re_qp_req {
+ __u64 qpsva;
+ __u64 qprva;
+ __u64 qp_handle;
+};
+struct bnxt_re_qp_resp {
+ __u32 qpid;
+ __u32 rsvd;
+};
+enum bnxt_re_shpg_offt {
+ BNXT_RE_BEG_RESV_OFFT = 0x00,
+ BNXT_RE_AVID_OFFT = 0x10,
+ BNXT_RE_AVID_SIZE = 0x04,
+ BNXT_RE_END_RESV_OFFT = 0xFF0
+};
+#endif
diff --git a/libc/kernel/uapi/rdma/hfi/hfi1_ioctl.h b/libc/kernel/uapi/rdma/hfi/hfi1_ioctl.h
new file mode 100644
index 0000000..ea828fb
--- /dev/null
+++ b/libc/kernel/uapi/rdma/hfi/hfi1_ioctl.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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__HFI1_IOCTL_H
+#define _LINUX__HFI1_IOCTL_H
+#include <linux/types.h>
+struct hfi1_user_info {
+ __u32 userversion;
+ __u32 pad;
+ __u16 subctxt_cnt;
+ __u16 subctxt_id;
+ __u8 uuid[16];
+};
+struct hfi1_ctxt_info {
+ __u64 runtime_flags;
+ __u32 rcvegr_size;
+ __u16 num_active;
+ __u16 unit;
+ __u16 ctxt;
+ __u16 subctxt;
+ __u16 rcvtids;
+ __u16 credits;
+ __u16 numa_node;
+ __u16 rec_cpu;
+ __u16 send_ctxt;
+ __u16 egrtids;
+ __u16 rcvhdrq_cnt;
+ __u16 rcvhdrq_entsize;
+ __u16 sdma_ring_size;
+};
+struct hfi1_tid_info {
+ __u64 vaddr;
+ __u64 tidlist;
+ __u32 tidcnt;
+ __u32 length;
+};
+struct hfi1_base_info {
+ __u32 hw_version;
+ __u32 sw_version;
+ __u16 jkey;
+ __u16 padding1;
+ __u32 bthqp;
+ __u64 sc_credits_addr;
+ __u64 pio_bufbase_sop;
+ __u64 pio_bufbase;
+ __u64 rcvhdr_bufbase;
+ __u64 rcvegr_bufbase;
+ __u64 sdma_comp_bufbase;
+ __u64 user_regbase;
+ __u64 events_bufbase;
+ __u64 status_bufbase;
+ __u64 rcvhdrtail_base;
+ __u64 subctxt_uregbase;
+ __u64 subctxt_rcvegrbuf;
+ __u64 subctxt_rcvhdrbuf;
+};
+#endif
diff --git a/libc/kernel/uapi/rdma/hfi/hfi1_user.h b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
index b45506d..0d840e9 100644
--- a/libc/kernel/uapi/rdma/hfi/hfi1_user.h
+++ b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
@@ -19,6 +19,7 @@
#ifndef _LINUX__HFI1_USER_H
#define _LINUX__HFI1_USER_H
#include <linux/types.h>
+#include <rdma/rdma_user_ioctl.h>
#define HFI1_USER_SWMAJOR 6
#define HFI1_USER_SWMINOR 3
#define HFI1_SWMAJOR_SHIFT 16
@@ -42,35 +43,6 @@
#define HFI1_RCVHDR_ENTSIZE_2 (1UL << 0)
#define HFI1_RCVHDR_ENTSIZE_16 (1UL << 1)
#define HFI1_RCVDHR_ENTSIZE_32 (1UL << 2)
-#define HFI1_CMD_ASSIGN_CTXT 1
-#define HFI1_CMD_CTXT_INFO 2
-#define HFI1_CMD_USER_INFO 3
-#define HFI1_CMD_TID_UPDATE 4
-#define HFI1_CMD_TID_FREE 5
-#define HFI1_CMD_CREDIT_UPD 6
-#define HFI1_CMD_RECV_CTRL 8
-#define HFI1_CMD_POLL_TYPE 9
-#define HFI1_CMD_ACK_EVENT 10
-#define HFI1_CMD_SET_PKEY 11
-#define HFI1_CMD_CTXT_RESET 12
-#define HFI1_CMD_TID_INVAL_READ 13
-#define HFI1_CMD_GET_VERS 14
-#define IB_IOCTL_MAGIC 0x1b
-#define __NUM(cmd) (HFI1_CMD_ ##cmd + 0xe0)
-struct hfi1_cmd;
-#define HFI1_IOCTL_ASSIGN_CTXT _IOWR(IB_IOCTL_MAGIC, __NUM(ASSIGN_CTXT), struct hfi1_user_info)
-#define HFI1_IOCTL_CTXT_INFO _IOW(IB_IOCTL_MAGIC, __NUM(CTXT_INFO), struct hfi1_ctxt_info)
-#define HFI1_IOCTL_USER_INFO _IOW(IB_IOCTL_MAGIC, __NUM(USER_INFO), struct hfi1_base_info)
-#define HFI1_IOCTL_TID_UPDATE _IOWR(IB_IOCTL_MAGIC, __NUM(TID_UPDATE), struct hfi1_tid_info)
-#define HFI1_IOCTL_TID_FREE _IOWR(IB_IOCTL_MAGIC, __NUM(TID_FREE), struct hfi1_tid_info)
-#define HFI1_IOCTL_CREDIT_UPD _IO(IB_IOCTL_MAGIC, __NUM(CREDIT_UPD))
-#define HFI1_IOCTL_RECV_CTRL _IOW(IB_IOCTL_MAGIC, __NUM(RECV_CTRL), int)
-#define HFI1_IOCTL_POLL_TYPE _IOW(IB_IOCTL_MAGIC, __NUM(POLL_TYPE), int)
-#define HFI1_IOCTL_ACK_EVENT _IOW(IB_IOCTL_MAGIC, __NUM(ACK_EVENT), unsigned long)
-#define HFI1_IOCTL_SET_PKEY _IOW(IB_IOCTL_MAGIC, __NUM(SET_PKEY), __u16)
-#define HFI1_IOCTL_CTXT_RESET _IO(IB_IOCTL_MAGIC, __NUM(CTXT_RESET))
-#define HFI1_IOCTL_TID_INVAL_READ _IOWR(IB_IOCTL_MAGIC, __NUM(TID_INVAL_READ), struct hfi1_tid_info)
-#define HFI1_IOCTL_GET_VERS _IOR(IB_IOCTL_MAGIC, __NUM(GET_VERS), int)
#define _HFI1_EVENT_FROZEN_BIT 0
#define _HFI1_EVENT_LINKDOWN_BIT 1
#define _HFI1_EVENT_LID_CHANGE_BIT 2
@@ -92,36 +64,6 @@
#define HFI1_MAX_SHARED_CTXTS 8
#define HFI1_POLL_TYPE_ANYRCV 0x0
#define HFI1_POLL_TYPE_URGENT 0x1
-struct hfi1_user_info {
- __u32 userversion;
- __u32 pad;
- __u16 subctxt_cnt;
- __u16 subctxt_id;
- __u8 uuid[16];
-};
-struct hfi1_ctxt_info {
- __u64 runtime_flags;
- __u32 rcvegr_size;
- __u16 num_active;
- __u16 unit;
- __u16 ctxt;
- __u16 subctxt;
- __u16 rcvtids;
- __u16 credits;
- __u16 numa_node;
- __u16 rec_cpu;
- __u16 send_ctxt;
- __u16 egrtids;
- __u16 rcvhdrq_cnt;
- __u16 rcvhdrq_entsize;
- __u16 sdma_ring_size;
-};
-struct hfi1_tid_info {
- __u64 vaddr;
- __u64 tidlist;
- __u32 tidcnt;
- __u32 length;
-};
enum hfi1_sdma_comp_state {
FREE = 0,
QUEUED,
@@ -137,26 +79,6 @@
__u64 port;
char freezemsg[0];
};
-struct hfi1_base_info {
- __u32 hw_version;
- __u32 sw_version;
- __u16 jkey;
- __u16 padding1;
- __u32 bthqp;
- __u64 sc_credits_addr;
- __u64 pio_bufbase_sop;
- __u64 pio_bufbase;
- __u64 rcvhdr_bufbase;
- __u64 rcvegr_bufbase;
- __u64 sdma_comp_bufbase;
- __u64 user_regbase;
- __u64 events_bufbase;
- __u64 status_bufbase;
- __u64 rcvhdrtail_base;
- __u64 subctxt_uregbase;
- __u64 subctxt_rcvegrbuf;
- __u64 subctxt_rcvhdrbuf;
-};
enum sdma_req_opcode {
EXPECTED = 0,
EAGER
diff --git a/libc/kernel/uapi/rdma/ib_user_mad.h b/libc/kernel/uapi/rdma/ib_user_mad.h
index 2aacb5c..cd723bb 100644
--- a/libc/kernel/uapi/rdma/ib_user_mad.h
+++ b/libc/kernel/uapi/rdma/ib_user_mad.h
@@ -19,7 +19,7 @@
#ifndef IB_USER_MAD_H
#define IB_USER_MAD_H
#include <linux/types.h>
-#include <linux/ioctl.h>
+#include <rdma/rdma_user_ioctl.h>
#define IB_USER_MAD_ABI_VERSION 5
struct ib_user_mad_hdr_old {
__u32 id;
@@ -90,9 +90,4 @@
__u8 rmpp_version;
__u8 reserved[3];
};
-#define IB_IOCTL_MAGIC 0x1b
-#define IB_USER_MAD_REGISTER_AGENT _IOWR(IB_IOCTL_MAGIC, 1, struct ib_user_mad_reg_req)
-#define IB_USER_MAD_UNREGISTER_AGENT _IOW(IB_IOCTL_MAGIC, 2, __u32)
-#define IB_USER_MAD_ENABLE_PKEY _IO(IB_IOCTL_MAGIC, 3)
-#define IB_USER_MAD_REGISTER_AGENT2 _IOWR(IB_IOCTL_MAGIC, 4, struct ib_user_mad_reg_req2)
#endif
diff --git a/libc/kernel/uapi/rdma/ib_user_verbs.h b/libc/kernel/uapi/rdma/ib_user_verbs.h
index c914006..4feb031 100644
--- a/libc/kernel/uapi/rdma/ib_user_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_verbs.h
@@ -184,7 +184,7 @@
__u64 device_cap_flags_ex;
struct ib_uverbs_rss_caps rss_caps;
__u32 max_wq_type_rq;
- __u32 reserved;
+ __u32 raw_packet_caps;
};
struct ib_uverbs_query_port {
__u64 response;
@@ -775,6 +775,28 @@
struct ib_uverbs_flow_ipv6_filter val;
struct ib_uverbs_flow_ipv6_filter mask;
};
+struct ib_uverbs_flow_spec_action_tag {
+ union {
+ struct ib_uverbs_flow_spec_hdr hdr;
+ struct {
+ __u32 type;
+ __u16 size;
+ __u16 reserved;
+ };
+ };
+ __u32 tag_id;
+ __u32 reserved1;
+};
+struct ib_uverbs_flow_spec_action_drop {
+ union {
+ struct ib_uverbs_flow_spec_hdr hdr;
+ struct {
+ __u32 type;
+ __u16 size;
+ __u16 reserved;
+ };
+ };
+};
struct ib_uverbs_flow_tunnel_filter {
__be32 tunnel_id;
};
@@ -876,6 +898,8 @@
__u32 cq_handle;
__u32 max_wr;
__u32 max_sge;
+ __u32 create_flags;
+ __u32 reserved;
};
struct ib_uverbs_ex_create_wq_resp {
__u32 comp_mask;
@@ -900,6 +924,8 @@
__u32 wq_handle;
__u32 wq_state;
__u32 curr_wq_state;
+ __u32 flags;
+ __u32 flags_mask;
};
#define IB_USER_VERBS_MAX_LOG_IND_TBL_SIZE 0x0d
struct ib_uverbs_ex_create_rwq_ind_table {
@@ -917,4 +943,5 @@
__u32 comp_mask;
__u32 ind_tbl_handle;
};
+#define IB_DEVICE_NAME_MAX 64
#endif
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index 1a8eb0d..6e76a3d 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -19,6 +19,7 @@
#ifndef MLX5_ABI_USER_H
#define MLX5_ABI_USER_H
#include <linux/types.h>
+#include <linux/if_ether.h>
enum {
MLX5_QP_FLAG_SIGNATURE = 1 << 0,
MLX5_QP_FLAG_SCATTER_CQE = 1 << 1,
@@ -31,18 +32,22 @@
};
#define MLX5_IB_UVERBS_ABI_VERSION 1
struct mlx5_ib_alloc_ucontext_req {
- __u32 total_num_uuars;
- __u32 num_low_latency_uuars;
+ __u32 total_num_bfregs;
+ __u32 num_low_latency_bfregs;
+};
+enum mlx5_lib_caps {
+ MLX5_LIB_CAP_4K_UAR = (__u64) 1 << 0,
};
struct mlx5_ib_alloc_ucontext_req_v2 {
- __u32 total_num_uuars;
- __u32 num_low_latency_uuars;
+ __u32 total_num_bfregs;
+ __u32 num_low_latency_bfregs;
__u32 flags;
__u32 comp_mask;
__u8 max_cqe_version;
__u8 reserved0;
__u16 reserved1;
__u32 reserved2;
+ __u64 lib_caps;
};
enum mlx5_ib_alloc_ucontext_resp_mask {
MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET = 1UL << 0,
@@ -51,10 +56,17 @@
MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE = 1 << 0,
MLX5_USER_CMDS_SUPP_UHW_CREATE_AH = 1 << 1,
};
+enum mlx5_user_inline_mode {
+ MLX5_USER_INLINE_MODE_NA,
+ MLX5_USER_INLINE_MODE_NONE,
+ MLX5_USER_INLINE_MODE_L2,
+ MLX5_USER_INLINE_MODE_IP,
+ MLX5_USER_INLINE_MODE_TCP_UDP,
+};
struct mlx5_ib_alloc_ucontext_resp {
__u32 qp_tab_size;
__u32 bf_reg_size;
- __u32 tot_uuars;
+ __u32 tot_bfregs;
__u32 cache_line_size;
__u16 max_sq_desc_sz;
__u16 max_rq_desc_sz;
@@ -67,8 +79,11 @@
__u32 response_length;
__u8 cqe_version;
__u8 cmds_supp_uhw;
- __u16 reserved2;
+ __u8 eth_min_inline;
+ __u8 reserved2;
__u64 hca_core_clock_offset;
+ __u32 log_uar_size;
+ __u32 num_uars_per_page;
};
struct mlx5_ib_alloc_pd_resp {
__u32 pdn;
@@ -171,7 +186,7 @@
__u32 reserved1;
};
struct mlx5_ib_create_qp_resp {
- __u32 uuar_index;
+ __u32 bfreg_index;
};
struct mlx5_ib_alloc_mw {
__u32 comp_mask;
diff --git a/libc/kernel/uapi/rdma/rdma_user_ioctl.h b/libc/kernel/uapi/rdma/rdma_user_ioctl.h
new file mode 100644
index 0000000..bb65c5d
--- /dev/null
+++ b/libc/kernel/uapi/rdma/rdma_user_ioctl.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 RDMA_USER_IOCTL_H
+#define RDMA_USER_IOCTL_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <rdma/ib_user_mad.h>
+#include <rdma/hfi/hfi1_ioctl.h>
+#define RDMA_IOCTL_MAGIC 0x1b
+#define IB_IOCTL_MAGIC RDMA_IOCTL_MAGIC
+#define IB_USER_MAD_REGISTER_AGENT _IOWR(RDMA_IOCTL_MAGIC, 0x01, struct ib_user_mad_reg_req)
+#define IB_USER_MAD_UNREGISTER_AGENT _IOW(RDMA_IOCTL_MAGIC, 0x02, __u32)
+#define IB_USER_MAD_ENABLE_PKEY _IO(RDMA_IOCTL_MAGIC, 0x03)
+#define IB_USER_MAD_REGISTER_AGENT2 _IOWR(RDMA_IOCTL_MAGIC, 0x04, struct ib_user_mad_reg_req2)
+#define HFI1_IOCTL_ASSIGN_CTXT _IOWR(RDMA_IOCTL_MAGIC, 0xE1, struct hfi1_user_info)
+#define HFI1_IOCTL_CTXT_INFO _IOW(RDMA_IOCTL_MAGIC, 0xE2, struct hfi1_ctxt_info)
+#define HFI1_IOCTL_USER_INFO _IOW(RDMA_IOCTL_MAGIC, 0xE3, struct hfi1_base_info)
+#define HFI1_IOCTL_TID_UPDATE _IOWR(RDMA_IOCTL_MAGIC, 0xE4, struct hfi1_tid_info)
+#define HFI1_IOCTL_TID_FREE _IOWR(RDMA_IOCTL_MAGIC, 0xE5, struct hfi1_tid_info)
+#define HFI1_IOCTL_CREDIT_UPD _IO(RDMA_IOCTL_MAGIC, 0xE6)
+#define HFI1_IOCTL_RECV_CTRL _IOW(RDMA_IOCTL_MAGIC, 0xE8, int)
+#define HFI1_IOCTL_POLL_TYPE _IOW(RDMA_IOCTL_MAGIC, 0xE9, int)
+#define HFI1_IOCTL_ACK_EVENT _IOW(RDMA_IOCTL_MAGIC, 0xEA, unsigned long)
+#define HFI1_IOCTL_SET_PKEY _IOW(RDMA_IOCTL_MAGIC, 0xEB, __u16)
+#define HFI1_IOCTL_CTXT_RESET _IO(RDMA_IOCTL_MAGIC, 0xEC)
+#define HFI1_IOCTL_TID_INVAL_READ _IOWR(RDMA_IOCTL_MAGIC, 0xED, struct hfi1_tid_info)
+#define HFI1_IOCTL_GET_VERS _IOR(RDMA_IOCTL_MAGIC, 0xEE, int)
+#endif
diff --git a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
index ab734f9..3666815 100644
--- a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
+++ b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
@@ -168,7 +168,7 @@
__u32 opcode;
__u32 send_flags;
union {
- __u32 imm_data;
+ __be32 imm_data;
__u32 invalidate_rkey;
} ex;
__u32 reserved;
@@ -216,7 +216,7 @@
__u32 opcode;
__u32 status;
__u32 byte_len;
- __u32 imm_data;
+ __be32 imm_data;
__u32 src_qp;
__u32 wc_flags;
__u32 vendor_err;
diff --git a/libc/kernel/uapi/scsi/cxlflash_ioctl.h b/libc/kernel/uapi/scsi/cxlflash_ioctl.h
index 9cde93a..91ffe62 100644
--- a/libc/kernel/uapi/scsi/cxlflash_ioctl.h
+++ b/libc/kernel/uapi/scsi/cxlflash_ioctl.h
@@ -28,6 +28,7 @@
};
#define DK_CXLFLASH_ALL_PORTS_ACTIVE 0x0000000000000001ULL
#define DK_CXLFLASH_APP_CLOSE_ADAP_FD 0x0000000000000002ULL
+#define DK_CXLFLASH_CONTEXT_SQ_CMD_MODE 0x0000000000000004ULL
#define DK_CXLFLASH_ATTACH_REUSE_CONTEXT 0x8000000000000000ULL
struct dk_cxlflash_attach {
struct dk_cxlflash_hdr hdr;
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index 8466ea1..e3041ce 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -69,7 +69,9 @@
SNDRV_HWDEP_IFACE_FW_DIGI00X,
SNDRV_HWDEP_IFACE_FW_TASCAM,
SNDRV_HWDEP_IFACE_LINE6,
- SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_LINE6
+ SNDRV_HWDEP_IFACE_FW_MOTU,
+ SNDRV_HWDEP_IFACE_FW_FIREFACE,
+ SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE
};
struct snd_hwdep_info {
unsigned int device;
diff --git a/libc/kernel/uapi/sound/firewire.h b/libc/kernel/uapi/sound/firewire.h
index fc478f8..91289c0 100644
--- a/libc/kernel/uapi/sound/firewire.h
+++ b/libc/kernel/uapi/sound/firewire.h
@@ -24,6 +24,7 @@
#define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e
#define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475
#define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c
+#define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479
struct snd_firewire_event_common {
unsigned int type;
};
@@ -53,12 +54,17 @@
unsigned int type;
__u32 message;
};
+struct snd_firewire_event_motu_notification {
+ unsigned int type;
+ __u32 message;
+};
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_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)
@@ -69,6 +75,8 @@
#define SNDRV_FIREWIRE_TYPE_OXFW 4
#define SNDRV_FIREWIRE_TYPE_DIGI00X 5
#define SNDRV_FIREWIRE_TYPE_TASCAM 6
+#define SNDRV_FIREWIRE_TYPE_MOTU 7
+#define SNDRV_FIREWIRE_TYPE_FIREFACE 8
struct snd_firewire_get_info {
unsigned int type;
unsigned int card;
diff --git a/libc/kernel/uapi/xen/privcmd.h b/libc/kernel/uapi/xen/privcmd.h
index b251e73..210a75e 100644
--- a/libc/kernel/uapi/xen/privcmd.h
+++ b/libc/kernel/uapi/xen/privcmd.h
@@ -50,8 +50,19 @@
const xen_pfn_t __user * arr;
int __user * err;
};
+struct privcmd_dm_op_buf {
+ void __user * uptr;
+ size_t size;
+};
+struct privcmd_dm_op {
+ domid_t dom;
+ __u16 num;
+ const struct privcmd_dm_op_buf __user * ubufs;
+};
#define IOCTL_PRIVCMD_HYPERCALL _IOC(_IOC_NONE, 'P', 0, sizeof(struct privcmd_hypercall))
#define IOCTL_PRIVCMD_MMAP _IOC(_IOC_NONE, 'P', 2, sizeof(struct privcmd_mmap))
#define IOCTL_PRIVCMD_MMAPBATCH _IOC(_IOC_NONE, 'P', 3, sizeof(struct privcmd_mmapbatch))
#define IOCTL_PRIVCMD_MMAPBATCH_V2 _IOC(_IOC_NONE, 'P', 4, sizeof(struct privcmd_mmapbatch_v2))
+#define IOCTL_PRIVCMD_DM_OP _IOC(_IOC_NONE, 'P', 5, sizeof(struct privcmd_dm_op))
+#define IOCTL_PRIVCMD_RESTRICT _IOC(_IOC_NONE, 'P', 6, sizeof(domid_t))
#endif
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index a4212dd..31c2a53 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -343,6 +343,7 @@
fdatasync;
fdopen;
fdopendir;
+ fdprintf; # arm x86 mips versioned=28
feof;
feof_unlocked; # introduced=23
ferror;
@@ -398,11 +399,11 @@
ftruncate;
ftruncate64; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
ftrylockfile;
- fts_children;
- fts_close;
- fts_open;
- fts_read;
- fts_set;
+ fts_children; # introduced=21
+ fts_close; # introduced=21
+ fts_open; # introduced=21
+ fts_read; # introduced=21
+ fts_set; # introduced=21
ftw; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
ftw64; # introduced=21
funlockfile;
@@ -1105,6 +1106,7 @@
vdprintf; # introduced=21
verr;
verrx;
+ vfdprintf; # arm x86 mips versioned=28
vfork;
vfprintf;
vfscanf;
@@ -1316,6 +1318,17 @@
wctrans_l; # introduced=26
} LIBC_N;
+LIBC_P {
+ global:
+ __freading; # future
+ __fwriting; # future
+ getlogin_r; # future
+ iconv; # future
+ iconv_close; # future
+ iconv_open; # future
+ syncfs; # future
+} LIBC_O;
+
LIBC_PRIVATE {
global:
___Unwind_Backtrace; # arm
@@ -1507,7 +1520,6 @@
dlmalloc_inspect_all; # arm x86 mips
dlmalloc_trim; # arm x86 mips
dlmalloc_usable_size; # arm x86 mips
- fdprintf; # arm x86 mips
free_malloc_leak_info;
ftime; # arm x86 mips
get_malloc_leak_info;
@@ -1529,10 +1541,9 @@
strtotimeval; # arm x86 mips
sysv_signal; # arm x86 mips
tkill; # arm x86 mips
- vfdprintf; # arm x86 mips
wait3; # arm x86 mips
wcswcs; # arm x86 mips
-} LIBC_O;
+} LIBC_P;
LIBC_DEPRECATED {
global:
@@ -1554,4 +1565,4 @@
malloc_disable;
malloc_enable;
malloc_iterate;
-} LIBC_O;
+} LIBC_P;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index bf0341a..6cc6d64 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -328,11 +328,11 @@
ftruncate;
ftruncate64; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
ftrylockfile;
- fts_children;
- fts_close;
- fts_open;
- fts_read;
- fts_set;
+ fts_children; # introduced=21
+ fts_close; # introduced=21
+ fts_open; # introduced=21
+ fts_read; # introduced=21
+ fts_set; # introduced=21
ftw; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
ftw64; # introduced=21
funlockfile;
@@ -1238,6 +1238,17 @@
wctrans_l; # introduced=26
} LIBC_N;
+LIBC_P {
+ global:
+ __freading; # future
+ __fwriting; # future
+ getlogin_r; # future
+ iconv; # future
+ iconv_close; # future
+ iconv_open; # future
+ syncfs; # future
+} LIBC_O;
+
LIBC_PRIVATE {
global:
android_getaddrinfofornet;
@@ -1249,7 +1260,7 @@
free_malloc_leak_info;
get_malloc_leak_info;
gMallocLeakZygoteChild;
-} LIBC_O;
+} LIBC_P;
LIBC_DEPRECATED {
global:
@@ -1271,4 +1282,4 @@
malloc_disable;
malloc_enable;
malloc_iterate;
-} LIBC_O;
+} LIBC_P;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index c271a57..5cbfaeb 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -345,6 +345,7 @@
fdatasync;
fdopen;
fdopendir;
+ fdprintf; # arm x86 mips versioned=28
feof;
feof_unlocked; # introduced=23
ferror;
@@ -400,11 +401,11 @@
ftruncate;
ftruncate64; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
ftrylockfile;
- fts_children;
- fts_close;
- fts_open;
- fts_read;
- fts_set;
+ fts_children; # introduced=21
+ fts_close; # introduced=21
+ fts_open; # introduced=21
+ fts_read; # introduced=21
+ fts_set; # introduced=21
ftw; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
ftw64; # introduced=21
funlockfile;
@@ -1130,6 +1131,7 @@
vdprintf; # introduced=21
verr;
verrx;
+ vfdprintf; # arm x86 mips versioned=28
vfork;
vfprintf;
vfscanf;
@@ -1341,6 +1343,17 @@
wctrans_l; # introduced=26
} LIBC_N;
+LIBC_P {
+ global:
+ __freading; # future
+ __fwriting; # future
+ getlogin_r; # future
+ iconv; # future
+ iconv_close; # future
+ iconv_open; # future
+ syncfs; # future
+} LIBC_O;
+
LIBC_PRIVATE {
global:
___Unwind_Backtrace; # arm
@@ -1533,7 +1546,6 @@
dlmalloc_inspect_all; # arm x86 mips
dlmalloc_trim; # arm x86 mips
dlmalloc_usable_size; # arm x86 mips
- fdprintf; # arm x86 mips
free_malloc_leak_info;
ftime; # arm x86 mips
get_malloc_leak_info;
@@ -1555,10 +1567,9 @@
strtotimeval; # arm x86 mips
sysv_signal; # arm x86 mips
tkill; # arm x86 mips
- vfdprintf; # arm x86 mips
wait3; # arm x86 mips
wcswcs; # arm x86 mips
-} LIBC_O;
+} LIBC_P;
LIBC_DEPRECATED {
global:
@@ -1580,4 +1591,4 @@
malloc_disable;
malloc_enable;
malloc_iterate;
-} LIBC_O;
+} LIBC_P;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 214c7f5..34369ba 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -341,6 +341,7 @@
fdatasync;
fdopen;
fdopendir;
+ fdprintf; # arm x86 mips versioned=28
feof;
feof_unlocked; # introduced=23
ferror;
@@ -396,11 +397,11 @@
ftruncate;
ftruncate64; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
ftrylockfile;
- fts_children;
- fts_close;
- fts_open;
- fts_read;
- fts_set;
+ fts_children; # introduced=21
+ fts_close; # introduced=21
+ fts_open; # introduced=21
+ fts_read; # introduced=21
+ fts_set; # introduced=21
ftw; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
ftw64; # introduced=21
funlockfile;
@@ -1103,6 +1104,7 @@
vdprintf; # introduced=21
verr;
verrx;
+ vfdprintf; # arm x86 mips versioned=28
vfork;
vfprintf;
vfscanf;
@@ -1300,6 +1302,17 @@
wctrans_l; # introduced=26
} LIBC_N;
+LIBC_P {
+ global:
+ __freading; # future
+ __fwriting; # future
+ getlogin_r; # future
+ iconv; # future
+ iconv_close; # future
+ iconv_open; # future
+ syncfs; # future
+} LIBC_O;
+
LIBC_PRIVATE {
global:
__accept4; # arm x86 mips
@@ -1349,7 +1362,6 @@
dlmalloc_inspect_all; # arm x86 mips
dlmalloc_trim; # arm x86 mips
dlmalloc_usable_size; # arm x86 mips
- fdprintf; # arm x86 mips
free_malloc_leak_info;
ftime; # arm x86 mips
get_malloc_leak_info;
@@ -1370,10 +1382,9 @@
strtotimeval; # arm x86 mips
sysv_signal; # arm x86 mips
tkill; # arm x86 mips
- vfdprintf; # arm x86 mips
wait3; # arm x86 mips
wcswcs; # arm x86 mips
-} LIBC_O;
+} LIBC_P;
LIBC_DEPRECATED {
global:
@@ -1395,4 +1406,4 @@
malloc_disable;
malloc_enable;
malloc_iterate;
-} LIBC_O;
+} LIBC_P;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index bf0341a..6cc6d64 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -328,11 +328,11 @@
ftruncate;
ftruncate64; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
ftrylockfile;
- fts_children;
- fts_close;
- fts_open;
- fts_read;
- fts_set;
+ fts_children; # introduced=21
+ fts_close; # introduced=21
+ fts_open; # introduced=21
+ fts_read; # introduced=21
+ fts_set; # introduced=21
ftw; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
ftw64; # introduced=21
funlockfile;
@@ -1238,6 +1238,17 @@
wctrans_l; # introduced=26
} LIBC_N;
+LIBC_P {
+ global:
+ __freading; # future
+ __fwriting; # future
+ getlogin_r; # future
+ iconv; # future
+ iconv_close; # future
+ iconv_open; # future
+ syncfs; # future
+} LIBC_O;
+
LIBC_PRIVATE {
global:
android_getaddrinfofornet;
@@ -1249,7 +1260,7 @@
free_malloc_leak_info;
get_malloc_leak_info;
gMallocLeakZygoteChild;
-} LIBC_O;
+} LIBC_P;
LIBC_DEPRECATED {
global:
@@ -1271,4 +1282,4 @@
malloc_disable;
malloc_enable;
malloc_iterate;
-} LIBC_O;
+} LIBC_P;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 145b64e..76dffa5 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -339,6 +339,7 @@
fdatasync;
fdopen;
fdopendir;
+ fdprintf; # arm x86 mips versioned=28
feof;
feof_unlocked; # introduced=23
ferror;
@@ -394,11 +395,11 @@
ftruncate;
ftruncate64; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
ftrylockfile;
- fts_children;
- fts_close;
- fts_open;
- fts_read;
- fts_set;
+ fts_children; # introduced=21
+ fts_close; # introduced=21
+ fts_open; # introduced=21
+ fts_read; # introduced=21
+ fts_set; # introduced=21
ftw; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
ftw64; # introduced=21
funlockfile;
@@ -1101,6 +1102,7 @@
vdprintf; # introduced=21
verr;
verrx;
+ vfdprintf; # arm x86 mips versioned=28
vfork;
vfprintf;
vfscanf;
@@ -1298,6 +1300,17 @@
wctrans_l; # introduced=26
} LIBC_N;
+LIBC_P {
+ global:
+ __freading; # future
+ __fwriting; # future
+ getlogin_r; # future
+ iconv; # future
+ iconv_close; # future
+ iconv_open; # future
+ syncfs; # future
+} LIBC_O;
+
LIBC_PRIVATE {
global:
__accept4; # arm x86 mips
@@ -1348,7 +1361,6 @@
dlmalloc_inspect_all; # arm x86 mips
dlmalloc_trim; # arm x86 mips
dlmalloc_usable_size; # arm x86 mips
- fdprintf; # arm x86 mips
free_malloc_leak_info;
ftime; # arm x86 mips
get_malloc_leak_info;
@@ -1369,10 +1381,9 @@
strtotimeval; # arm x86 mips
sysv_signal; # arm x86 mips
tkill; # arm x86 mips
- vfdprintf; # arm x86 mips
wait3; # arm x86 mips
wcswcs; # arm x86 mips
-} LIBC_O;
+} LIBC_P;
LIBC_DEPRECATED {
global:
@@ -1394,4 +1405,4 @@
malloc_disable;
malloc_enable;
malloc_iterate;
-} LIBC_O;
+} LIBC_P;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index bf0341a..6cc6d64 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -328,11 +328,11 @@
ftruncate;
ftruncate64; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
ftrylockfile;
- fts_children;
- fts_close;
- fts_open;
- fts_read;
- fts_set;
+ fts_children; # introduced=21
+ fts_close; # introduced=21
+ fts_open; # introduced=21
+ fts_read; # introduced=21
+ fts_set; # introduced=21
ftw; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
ftw64; # introduced=21
funlockfile;
@@ -1238,6 +1238,17 @@
wctrans_l; # introduced=26
} LIBC_N;
+LIBC_P {
+ global:
+ __freading; # future
+ __fwriting; # future
+ getlogin_r; # future
+ iconv; # future
+ iconv_close; # future
+ iconv_open; # future
+ syncfs; # future
+} LIBC_O;
+
LIBC_PRIVATE {
global:
android_getaddrinfofornet;
@@ -1249,7 +1260,7 @@
free_malloc_leak_info;
get_malloc_leak_info;
gMallocLeakZygoteChild;
-} LIBC_O;
+} LIBC_P;
LIBC_DEPRECATED {
global:
@@ -1271,4 +1282,4 @@
malloc_disable;
malloc_enable;
malloc_iterate;
-} LIBC_O;
+} LIBC_P;
diff --git a/libc/libstdc++.arm.map b/libc/libstdc++.arm.map
index b6b269d..8ee5863 100644
--- a/libc/libstdc++.arm.map
+++ b/libc/libstdc++.arm.map
@@ -2,14 +2,14 @@
LIBC_O {
global:
_ZSt7nothrow; # var
- _ZdaPv;
- _ZdaPvRKSt9nothrow_t;
- _ZdlPv;
- _ZdlPvRKSt9nothrow_t;
- _Znaj; # arm x86 mips
- _ZnajRKSt9nothrow_t; # arm x86 mips
- _Znwj; # arm x86 mips
- _ZnwjRKSt9nothrow_t; # arm x86 mips
+ _ZdaPv; # weak
+ _ZdaPvRKSt9nothrow_t; # weak
+ _ZdlPv; # weak
+ _ZdlPvRKSt9nothrow_t; # weak
+ _Znaj; # arm x86 mips weak
+ _ZnajRKSt9nothrow_t; # arm x86 mips weak
+ _Znwj; # arm x86 mips weak
+ _ZnwjRKSt9nothrow_t; # arm x86 mips weak
__cxa_guard_abort;
__cxa_guard_acquire;
__cxa_guard_release;
diff --git a/libc/libstdc++.arm64.map b/libc/libstdc++.arm64.map
index d0433c9..cd4f3c3 100644
--- a/libc/libstdc++.arm64.map
+++ b/libc/libstdc++.arm64.map
@@ -2,14 +2,14 @@
LIBC_O {
global:
_ZSt7nothrow; # var
- _ZdaPv;
- _ZdaPvRKSt9nothrow_t;
- _ZdlPv;
- _ZdlPvRKSt9nothrow_t;
- _Znam; # arm64 x86_64 mips64
- _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64
- _Znwm; # arm64 x86_64 mips64
- _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64
+ _ZdaPv; # weak
+ _ZdaPvRKSt9nothrow_t; # weak
+ _ZdlPv; # weak
+ _ZdlPvRKSt9nothrow_t; # weak
+ _Znam; # arm64 x86_64 mips64 weak
+ _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64 weak
+ _Znwm; # arm64 x86_64 mips64 weak
+ _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64 weak
__cxa_guard_abort;
__cxa_guard_acquire;
__cxa_guard_release;
diff --git a/libc/libstdc++.map.txt b/libc/libstdc++.map.txt
index 32d5d49..0a242d5 100644
--- a/libc/libstdc++.map.txt
+++ b/libc/libstdc++.map.txt
@@ -1,18 +1,18 @@
LIBC_O {
global:
_ZSt7nothrow; # var
- _ZdaPv;
- _ZdaPvRKSt9nothrow_t;
- _ZdlPv;
- _ZdlPvRKSt9nothrow_t;
- _Znaj; # arm x86 mips
- _ZnajRKSt9nothrow_t; # arm x86 mips
- _Znam; # arm64 x86_64 mips64
- _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64
- _Znwj; # arm x86 mips
- _ZnwjRKSt9nothrow_t; # arm x86 mips
- _Znwm; # arm64 x86_64 mips64
- _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64
+ _ZdaPv; # weak
+ _ZdaPvRKSt9nothrow_t; # weak
+ _ZdlPv; # weak
+ _ZdlPvRKSt9nothrow_t; # weak
+ _Znaj; # arm x86 mips weak
+ _ZnajRKSt9nothrow_t; # arm x86 mips weak
+ _Znam; # arm64 x86_64 mips64 weak
+ _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64 weak
+ _Znwj; # arm x86 mips weak
+ _ZnwjRKSt9nothrow_t; # arm x86 mips weak
+ _Znwm; # arm64 x86_64 mips64 weak
+ _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64 weak
__cxa_guard_abort;
__cxa_guard_acquire;
__cxa_guard_release;
diff --git a/libc/libstdc++.mips.map b/libc/libstdc++.mips.map
index b6b269d..8ee5863 100644
--- a/libc/libstdc++.mips.map
+++ b/libc/libstdc++.mips.map
@@ -2,14 +2,14 @@
LIBC_O {
global:
_ZSt7nothrow; # var
- _ZdaPv;
- _ZdaPvRKSt9nothrow_t;
- _ZdlPv;
- _ZdlPvRKSt9nothrow_t;
- _Znaj; # arm x86 mips
- _ZnajRKSt9nothrow_t; # arm x86 mips
- _Znwj; # arm x86 mips
- _ZnwjRKSt9nothrow_t; # arm x86 mips
+ _ZdaPv; # weak
+ _ZdaPvRKSt9nothrow_t; # weak
+ _ZdlPv; # weak
+ _ZdlPvRKSt9nothrow_t; # weak
+ _Znaj; # arm x86 mips weak
+ _ZnajRKSt9nothrow_t; # arm x86 mips weak
+ _Znwj; # arm x86 mips weak
+ _ZnwjRKSt9nothrow_t; # arm x86 mips weak
__cxa_guard_abort;
__cxa_guard_acquire;
__cxa_guard_release;
diff --git a/libc/libstdc++.mips64.map b/libc/libstdc++.mips64.map
index d0433c9..cd4f3c3 100644
--- a/libc/libstdc++.mips64.map
+++ b/libc/libstdc++.mips64.map
@@ -2,14 +2,14 @@
LIBC_O {
global:
_ZSt7nothrow; # var
- _ZdaPv;
- _ZdaPvRKSt9nothrow_t;
- _ZdlPv;
- _ZdlPvRKSt9nothrow_t;
- _Znam; # arm64 x86_64 mips64
- _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64
- _Znwm; # arm64 x86_64 mips64
- _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64
+ _ZdaPv; # weak
+ _ZdaPvRKSt9nothrow_t; # weak
+ _ZdlPv; # weak
+ _ZdlPvRKSt9nothrow_t; # weak
+ _Znam; # arm64 x86_64 mips64 weak
+ _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64 weak
+ _Znwm; # arm64 x86_64 mips64 weak
+ _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64 weak
__cxa_guard_abort;
__cxa_guard_acquire;
__cxa_guard_release;
diff --git a/libc/libstdc++.x86.map b/libc/libstdc++.x86.map
index b6b269d..8ee5863 100644
--- a/libc/libstdc++.x86.map
+++ b/libc/libstdc++.x86.map
@@ -2,14 +2,14 @@
LIBC_O {
global:
_ZSt7nothrow; # var
- _ZdaPv;
- _ZdaPvRKSt9nothrow_t;
- _ZdlPv;
- _ZdlPvRKSt9nothrow_t;
- _Znaj; # arm x86 mips
- _ZnajRKSt9nothrow_t; # arm x86 mips
- _Znwj; # arm x86 mips
- _ZnwjRKSt9nothrow_t; # arm x86 mips
+ _ZdaPv; # weak
+ _ZdaPvRKSt9nothrow_t; # weak
+ _ZdlPv; # weak
+ _ZdlPvRKSt9nothrow_t; # weak
+ _Znaj; # arm x86 mips weak
+ _ZnajRKSt9nothrow_t; # arm x86 mips weak
+ _Znwj; # arm x86 mips weak
+ _ZnwjRKSt9nothrow_t; # arm x86 mips weak
__cxa_guard_abort;
__cxa_guard_acquire;
__cxa_guard_release;
diff --git a/libc/libstdc++.x86_64.map b/libc/libstdc++.x86_64.map
index d0433c9..cd4f3c3 100644
--- a/libc/libstdc++.x86_64.map
+++ b/libc/libstdc++.x86_64.map
@@ -2,14 +2,14 @@
LIBC_O {
global:
_ZSt7nothrow; # var
- _ZdaPv;
- _ZdaPvRKSt9nothrow_t;
- _ZdlPv;
- _ZdlPvRKSt9nothrow_t;
- _Znam; # arm64 x86_64 mips64
- _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64
- _Znwm; # arm64 x86_64 mips64
- _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64
+ _ZdaPv; # weak
+ _ZdaPvRKSt9nothrow_t; # weak
+ _ZdlPv; # weak
+ _ZdlPvRKSt9nothrow_t; # weak
+ _Znam; # arm64 x86_64 mips64 weak
+ _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64 weak
+ _Znwm; # arm64 x86_64 mips64 weak
+ _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64 weak
__cxa_guard_abort;
__cxa_guard_acquire;
__cxa_guard_release;
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index b77af6d..03a8a73 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -371,6 +371,9 @@
Examples
========
+
+### For platform developers
+
Enable backtrace tracking of all allocation for all processes:
adb shell stop
@@ -427,17 +430,7 @@
but, obviously, it must be enabled through the signal before the file will
contain any data.
-To analyze the data produced by the dumpheap command, run this script:
-
- development/scripts/native_heapdump_viewer.py
-
-In order for the script to properly symbolize the stacks in the file,
-make sure the script is executed from the tree that built the image.
-Below is an example of how to execute the script using the dump created by the
-above command:
-
- adb shell pull /data/local/tmp/heap.txt .
- development/scripts/native_heapdump_viewer.py heap.txt > heap_info.txt
+### For app developers
Enable malloc debug for a specific program/application (Android O or later):
@@ -453,3 +446,40 @@
was necessary to truncate the name to fit. On O, property names can be
an order of magnitude larger, so there should be no need to truncate the name
at all.
+
+To detect leaks while an app is running:
+
+ adb shell dumpsys meminfo --unreachable <PID_OF_APP>
+
+Without also enabling malloc debug, this command will only tell
+you whether it can detect leaked memory, not where those leaks are
+occurring. If you enable malloc debug with the backtrace option for your
+app before running the dumpsys command, you'll get backtraces showing
+where the memory was allocated.
+
+For backtraces from your app to be useful, you'll want to keep the
+symbols in your app's shared libraries rather than stripping them. That
+way you'll see the location of the leak directly without having to use
+something like the <code>ndk-stack</code> tool.
+
+### Analyzing heap dumps
+
+To analyze the data produced by the dumpheap command, run this script:
+
+ development/scripts/native_heapdump_viewer.py
+
+In order for the script to properly symbolize the stacks in the file,
+make sure the script is executed from the tree that built the image.
+
+To collect, transfer, and analyze a dump:
+
+ adb shell am dumpheap -n <PID_TO_DUMP> /data/local/tmp/heap.txt
+ adb shell pull /data/local/tmp/heap.txt .
+ python development/scripts/native_heapdump_viewer.py --symbols /some/path/to/symbols/ heap.txt > heap_info.txt
+
+At the moment, the script will look for symbols in the given directory,
+using the path the .so file would have on the device. So if your .so file
+is at `/data/app/.../lib/arm/libx.so` on the device, it will need to be at
+`/some/path/to/symbols/data/app/.../lib/arm/libx.so` locally given the
+command line above. That is: you need to mirror the directory structure
+for the app in the symbols directory.
diff --git a/libc/private/CFIShadow.h b/libc/private/CFIShadow.h
index 26351db..1423d86 100644
--- a/libc/private/CFIShadow.h
+++ b/libc/private/CFIShadow.h
@@ -61,10 +61,8 @@
// Alignment of __cfi_check.
static constexpr uintptr_t kCfiCheckAlign = 1UL << kCfiCheckGranularity; // 4K
-#if defined(__aarch64__)
- static constexpr uintptr_t kMaxTargetAddr = 0x7fffffffff;
-#elif defined (__LP64__)
- static constexpr uintptr_t kMaxTargetAddr = 0x7fffffffffff;
+#if defined (__LP64__)
+ static constexpr uintptr_t kMaxTargetAddr = 0xffffffffffff;
#else
static constexpr uintptr_t kMaxTargetAddr = 0xffffffff;
#endif
diff --git a/libc/private/bionic_futex.h b/libc/private/bionic_futex.h
index 946d9dd..9b89131 100644
--- a/libc/private/bionic_futex.h
+++ b/libc/private/bionic_futex.h
@@ -36,13 +36,10 @@
#include <sys/syscall.h>
#include <unistd.h>
-__BEGIN_DECLS
-
struct timespec;
static inline __always_inline int __futex(volatile void* ftx, int op, int value,
- const struct timespec* timeout,
- int bitset) {
+ const timespec* timeout, int bitset) {
// Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to.
int saved_errno = errno;
int result = syscall(__NR_futex, ftx, op, value, timeout, NULL, bitset);
@@ -61,17 +58,16 @@
return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL, 0);
}
-static inline int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
+static inline int __futex_wait(volatile void* ftx, int value, const timespec* timeout) {
return __futex(ftx, FUTEX_WAIT, value, timeout, 0);
}
-static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value,
- bool use_realtime_clock, const struct timespec* abs_timeout) {
- return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE) |
- (use_realtime_clock ? FUTEX_CLOCK_REALTIME : 0), value, abs_timeout,
+static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value) {
+ return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE), value, nullptr,
FUTEX_BITSET_MATCH_ANY);
}
-__END_DECLS
+__LIBC_HIDDEN__ int __futex_wait_ex(volatile void* ftx, bool shared, int value,
+ bool use_realtime_clock, const timespec* abs_timeout);
#endif /* _BIONIC_FUTEX_H */
diff --git a/libc/private/bionic_lock.h b/libc/private/bionic_lock.h
index 3dbafe0..b389247 100644
--- a/libc/private/bionic_lock.h
+++ b/libc/private/bionic_lock.h
@@ -64,7 +64,7 @@
}
while (atomic_exchange_explicit(&state, LockedWithWaiter, memory_order_acquire) != Unlocked) {
// TODO: As the critical section is brief, it is a better choice to spin a few times befor sleeping.
- __futex_wait_ex(&state, process_shared, LockedWithWaiter, false, nullptr);
+ __futex_wait_ex(&state, process_shared, LockedWithWaiter);
}
return;
}
diff --git a/libc/private/bionic_mbstate.h b/libc/private/bionic_mbstate.h
index 018b47c..292959a 100644
--- a/libc/private/bionic_mbstate.h
+++ b/libc/private/bionic_mbstate.h
@@ -43,11 +43,31 @@
#define __MB_IS_ERR(rv) (rv == __MB_ERR_ILLEGAL_SEQUENCE || \
rv == __MB_ERR_INCOMPLETE_SEQUENCE)
-size_t mbstate_bytes_so_far(const mbstate_t* ps);
-void mbstate_set_byte(mbstate_t* ps, int i, char byte);
-uint8_t mbstate_get_byte(const mbstate_t* ps, int n);
-size_t reset_and_return_illegal(int _errno, mbstate_t* ps);
-size_t reset_and_return(int _return, mbstate_t* ps);
+static inline __wur size_t mbstate_bytes_so_far(const mbstate_t* ps) {
+ return
+ (ps->__seq[2] != 0) ? 3 :
+ (ps->__seq[1] != 0) ? 2 :
+ (ps->__seq[0] != 0) ? 1 : 0;
+}
+
+static inline void mbstate_set_byte(mbstate_t* ps, int i, char byte) {
+ ps->__seq[i] = static_cast<uint8_t>(byte);
+}
+
+static inline __wur uint8_t mbstate_get_byte(const mbstate_t* ps, int n) {
+ return ps->__seq[n];
+}
+
+static inline __wur size_t mbstate_reset_and_return_illegal(int _errno, mbstate_t* ps) {
+ errno = _errno;
+ *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
+ return __MB_ERR_ILLEGAL_SEQUENCE;
+}
+
+static inline __wur size_t mbstate_reset_and_return(int _return, mbstate_t* ps) {
+ *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
+ return _return;
+}
__END_DECLS
diff --git a/libc/private/bionic_time_conversions.h b/libc/private/bionic_time_conversions.h
index b9eaad2..fb049f2 100644
--- a/libc/private/bionic_time_conversions.h
+++ b/libc/private/bionic_time_conversions.h
@@ -42,6 +42,9 @@
__LIBC_HIDDEN__ void timeval_from_timespec(timeval& tv, const timespec& ts);
+__LIBC_HIDDEN__ void monotonic_time_from_realtime_time(timespec& monotonic_time,
+ const timespec& realtime_time);
+
__END_DECLS
static inline int check_timespec(const timespec* ts, bool null_allowed) {
diff --git a/libc/private/icu.h b/libc/private/icu.h
index 03fdf66..a671e98 100644
--- a/libc/private/icu.h
+++ b/libc/private/icu.h
@@ -30,12 +30,17 @@
#define _PRIVATE_ICU_H
#include <stdint.h>
+#include <wchar.h>
typedef int8_t UBool;
+#define FALSE 0
+#define TRUE 1
+
typedef int32_t UChar32;
enum UProperty {
UCHAR_ALPHABETIC = 0,
+ UCHAR_DEFAULT_IGNORABLE_CODE_POINT = 5,
UCHAR_LOWERCASE = 22,
UCHAR_POSIX_ALNUM = 44,
UCHAR_POSIX_BLANK = 45,
@@ -44,12 +49,39 @@
UCHAR_POSIX_XDIGIT = 48,
UCHAR_UPPERCASE = 30,
UCHAR_WHITE_SPACE = 31,
+ UCHAR_EAST_ASIAN_WIDTH = 0x1004,
+ UCHAR_HANGUL_SYLLABLE_TYPE = 0x100b,
};
enum UCharCategory {
+ U_NON_SPACING_MARK = 6,
+ U_ENCLOSING_MARK = 7,
U_CONTROL_CHAR = 15,
+ U_FORMAT_CHAR = 16,
};
+enum UEastAsianWidth {
+ U_EA_NEUTRAL,
+ U_EA_AMBIGUOUS,
+ U_EA_HALFWIDTH,
+ U_EA_FULLWIDTH,
+ U_EA_NARROW,
+ U_EA_WIDE,
+};
+
+enum UHangulSyllableType {
+ U_HST_NOT_APPLICABLE,
+ U_HST_LEADING_JAMO,
+ U_HST_VOWEL_JAMO,
+ U_HST_TRAILING_JAMO,
+ U_HST_LV_SYLLABLE,
+ U_HST_LVT_SYLLABLE,
+};
+
+int8_t __icu_charType(wint_t wc);
+int32_t __icu_getIntPropertyValue(wint_t wc, UProperty property);
+bool __icu_hasBinaryProperty(wint_t wc, UProperty property, int (*fallback)(int));
+
void* __find_icu_symbol(const char* symbol_name);
#endif // _PRIVATE_ICU_H
diff --git a/libc/seccomp/Android.bp b/libc/seccomp/Android.bp
index c341781..a75aa65 100644
--- a/libc/seccomp/Android.bp
+++ b/libc/seccomp/Android.bp
@@ -3,11 +3,17 @@
srcs: [
"seccomp_policy.cpp",
"arm_policy.cpp",
+ "arm_global_policy.cpp",
"arm64_policy.cpp",
+ "arm64_global_policy.cpp",
"x86_policy.cpp",
+ "x86_global_policy.cpp",
"x86_64_policy.cpp",
+ "x86_64_global_policy.cpp",
"mips_policy.cpp",
+ "mips_global_policy.cpp",
"mips64_policy.cpp",
+ "mips64_global_policy.cpp",
],
export_include_dirs: ["include"],
shared: {
diff --git a/libc/seccomp/arm64_global_policy.cpp b/libc/seccomp/arm64_global_policy.cpp
new file mode 100644
index 0000000..1a138b7
--- /dev/null
+++ b/libc/seccomp/arm64_global_policy.cpp
@@ -0,0 +1,43 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter arm64_global_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 0, 32),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 18, 27, 26), //setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 42, 26, 25), //eventfd2|epoll_create1|epoll_ctl|epoll_pwait|dup|dup3|fcntl|inotify_init1|inotify_add_watch|inotify_rm_watch|ioctl|ioprio_set|ioprio_get|flock|mknodat|mkdirat|unlinkat|symlinkat|linkat|renameat|umount2|mount|pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 59, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 24, 23), //statfs|fstatfs|truncate|ftruncate|fallocate|faccessat|chdir|fchdir|chroot|fchmod|fchmodat|fchownat|fchown|openat|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 99, 23, 22), //pipe2|quotactl|getdents64|lseek|read|write|readv|writev|pread64|pwrite64|preadv|pwritev|sendfile|pselect6|ppoll|signalfd4|vmsplice|splice|tee|readlinkat|newfstatat|fstat|sync|fsync|fdatasync|sync_file_range|timerfd_create|timerfd_settime|timerfd_gettime|utimensat|acct|capget|capset|personality|exit|exit_group|waitid|set_tid_address|unshare|futex
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 105, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 104, 20, 19), //nanosleep|getitimer|setitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 19, 18), //init_module|delete_module|timer_create|timer_gettime|timer_getoverrun|timer_settime|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|syslog|ptrace|sched_setparam|sched_setscheduler|sched_getscheduler|sched_getparam|sched_setaffinity|sched_getaffinity|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|restart_syscall|kill|tkill|tgkill|sigaltstack|rt_sigsuspend|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigreturn|setpriority|getpriority|reboot|setregid|setgid|setreuid|setuid|setresuid|getresuid|setresgid|getresgid|setfsuid|setfsgid|times|setpgid|getpgid|getsid|setsid|getgroups|setgroups|uname|sethostname|setdomainname|getrlimit|setrlimit|getrusage|umask|prctl|getcpu|gettimeofday|settimeofday|adjtimex|getpid|getppid|getuid|geteuid|getgid|getegid|gettid|sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 203, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 17, 16), //socket|socketpair|bind|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 16, 15), //connect|getsockname|getpeername|sendto|recvfrom|setsockopt|getsockopt|shutdown|sendmsg|recvmsg|readahead|brk|munmap|mremap|add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 266, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 240, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 226, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 225, 12, 11), //keyctl|clone|execve|mmap|fadvise64|swapon
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 234, 11, 10), //mprotect|msync|mlock|munlock|mlockall|munlockall|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 260, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 9, 8), //rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 8, 7), //wait4|prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 281, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 5, 4), //clock_adjtime|syncfs|setns|sendmmsg|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 4, 3), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 288, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t arm64_global_filter_size = sizeof(arm64_global_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/arm_global_policy.cpp b/libc/seccomp/arm_global_policy.cpp
new file mode 100644
index 0000000..2f9a122
--- /dev/null
+++ b/libc/seccomp/arm_global_policy.cpp
@@ -0,0 +1,143 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter arm_global_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 132),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 65, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 33, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 17, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 124, 123), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 123, 122), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 122, 121), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 120, 119), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 119, 118), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 116, 115), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 115, 114), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 113, 112), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 112, 111), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 108, 107), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 107, 106), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 105, 104), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 104, 103), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 101, 100), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 100, 99), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 98, 97), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 97, 96), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 87, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 92, 91), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 91, 90), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 89, 88), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 88, 87), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 103, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 85, 84), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 84, 83), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 82, 81), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 81, 80), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 77, 76), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 76, 75), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 74, 73), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 73, 72), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 70, 69), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 69, 68), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 67, 66), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 66, 65), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 309, 33, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 248, 17, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 59, 58), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 58, 57), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 57, 56), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 55, 54), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 54, 53), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 51, 50), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 50, 49), //getdents64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 48, 47), //mincore|madvise|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 243, 47, 46), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 43, 42), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 42, 41), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 270, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 40, 39), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 39, 38), //arm_fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 290, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 36, 35), //waitid|socket|bind|connect|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 35, 34), //getsockname|getpeername|socketpair
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 292, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 33, 32), //sendto
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 298, 32, 31), //recvfrom|shutdown|setsockopt|getsockopt|sendmsg|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 327, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 316, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 310, 27, 26), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 312, 26, 25), //keyctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 319, 24, 23), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 326, 23, 22), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 338, 20, 19), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 344, 19, 18), //splice|sync_file_range2|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 348, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 347, 17, 16), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 16, 15), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 387, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 372, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 369, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 367, 12, 11), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg|accept4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 370, 11, 10), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 379, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 378, 9, 8), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 386, 8, 7), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983042, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 390, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 388, 5, 4), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 394, 4, 3), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983045, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983043, 2, 1), //__ARM_NR_cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983046, 1, 0), //__ARM_NR_set_tls
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t arm_global_filter_size = sizeof(arm_global_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/include/seccomp_policy.h b/libc/seccomp/include/seccomp_policy.h
index 397f8e4..e337dec 100644
--- a/libc/seccomp/include/seccomp_policy.h
+++ b/libc/seccomp/include/seccomp_policy.h
@@ -21,6 +21,7 @@
#include <linux/filter.h>
bool set_seccomp_filter();
+bool set_global_seccomp_filter();
void get_seccomp_filter(const sock_filter*& filter, size_t& filter_size);
#endif
diff --git a/libc/seccomp/mips64_global_policy.cpp b/libc/seccomp/mips64_global_policy.cpp
new file mode 100644
index 0000000..004eda2
--- /dev/null
+++ b/libc/seccomp/mips64_global_policy.cpp
@@ -0,0 +1,97 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter mips64_global_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 86),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5168, 43, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5077, 21, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5034, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5008, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5005, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5003, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5002, 79, 78), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5004, 78, 77), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5006, 77, 76), //fstat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5031, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5023, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5020, 74, 73), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|ioctl|pread64|pwrite64|readv|writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5028, 73, 72), //sched_yield|mremap|msync|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5032, 72, 71), //dup
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5057, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5043, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5038, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5037, 68, 67), //nanosleep|getitimer|setitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5042, 67, 66), //getpid|sendfile|socket|connect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5056, 66, 65), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5070, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5062, 64, 63), //execve|exit|wait4|kill|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5076, 63, 62), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5134, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5093, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5091, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5089, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5080, 58, 57), //getcwd|chdir|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5090, 57, 56), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5092, 56, 55), //fchown
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5132, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5110, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5109, 53, 52), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid|syslog|getgid|setuid|setgid|geteuid|getegid|setpgid|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5130, 52, 51), //setsid|setreuid|setregid|getgroups|setgroups|setresuid|getresuid|setresgid|getresgid|getpgid|setfsuid|setfsgid|getsid|capget|capset|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5133, 51, 50), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5153, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5151, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5137, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5136, 47, 46), //statfs|fstatfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5150, 46, 45), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5152, 45, 44), //pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5164, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5163, 43, 42), //prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2|swapon
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5167, 42, 41), //reboot|sethostname|setdomainname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5244, 21, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5211, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5194, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5178, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5172, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5170, 36, 35), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5173, 35, 34), //quotactl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5193, 34, 33), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5208, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5205, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5198, 31, 30), //futex|sched_setaffinity|sched_getaffinity|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5206, 30, 29), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5209, 29, 28), //epoll_ctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5239, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5237, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5215, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5214, 25, 24), //rt_sigreturn|set_tid_address|restart_syscall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5226, 24, 23), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5238, 23, 22), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5241, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5240, 21, 20), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5243, 20, 19), //keyctl|set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5297, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5271, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5252, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5247, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5246, 15, 14), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5251, 14, 13), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5267, 13, 12), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5279, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5276, 11, 10), //getcpu|epoll_pwait|ioprio_set|ioprio_get|utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5295, 10, 9), //fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5316, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5307, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5300, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5298, 6, 5), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5306, 5, 4), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5315, 4, 3), //finit_module|getdents64|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5319, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5317, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5323, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t mips64_global_filter_size = sizeof(mips64_global_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/mips_global_policy.cpp b/libc/seccomp/mips_global_policy.cpp
new file mode 100644
index 0000000..b4fa23d
--- /dev/null
+++ b/libc/seccomp/mips_global_policy.cpp
@@ -0,0 +1,125 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter mips_global_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 114),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 57, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4023, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4010, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4008, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 107, 106), //exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 106, 105), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4019, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 104, 103), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 103, 102), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4033, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 100, 99), //setuid|getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 99, 98), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 97, 96), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 96, 95), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 92, 91), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 91, 90), //brk|setgid|getgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 89, 88), //geteuid|getegid|acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 88, 87), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 85, 84), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 84, 83), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 83, 82), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4103, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4087, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4074, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4070, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 78, 77), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 77, 76), //setreuid|setregid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 75, 74), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 74, 73), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4090, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 71, 70), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 70, 69), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 69, 68), //fchmod|fchown|getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4116, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4114, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 65, 64), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 64, 63), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 62, 61), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 61, 60), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 58, 57), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 57, 56), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 56, 55), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4248, 27, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 50, 49), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 49, 48), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 47, 46), //getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 46, 45), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 43, 42), //bind|connect|getpeername|getsockname|getsockopt|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 42, 41), //recvfrom|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 41, 40), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 37, 36), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 36, 35), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 34, 33), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 33, 32), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4246, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 30, 29), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4241, 29, 28), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 28, 27), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4316, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4288, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4280, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4278, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 23, 22), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4279, 22, 21), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4282, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4281, 20, 19), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4287, 19, 18), //keyctl|set_thread_area|inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4312, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4293, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4292, 16, 15), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4308, 15, 14), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4314, 14, 13), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4348, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4338, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4319, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4317, 10, 9), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4336, 9, 8), //eventfd|fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4341, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4339, 7, 6), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4347, 6, 5), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4359, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4356, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4355, 3, 2), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4357, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4363, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t mips_global_filter_size = sizeof(mips_global_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/seccomp_bpfs.h b/libc/seccomp/seccomp_bpfs.h
index 96e127e..a8f47ca 100644
--- a/libc/seccomp/seccomp_bpfs.h
+++ b/libc/seccomp/seccomp_bpfs.h
@@ -22,15 +22,27 @@
extern const struct sock_filter arm_filter[];
extern const size_t arm_filter_size;
+extern const struct sock_filter arm_global_filter[];
+extern const size_t arm_global_filter_size;
extern const struct sock_filter arm64_filter[];
extern const size_t arm64_filter_size;
+extern const struct sock_filter arm64_global_filter[];
+extern const size_t arm64_global_filter_size;
extern const struct sock_filter x86_filter[];
extern const size_t x86_filter_size;
+extern const struct sock_filter x86_global_filter[];
+extern const size_t x86_global_filter_size;
extern const struct sock_filter x86_64_filter[];
extern const size_t x86_64_filter_size;
+extern const struct sock_filter x86_64_global_filter[];
+extern const size_t x86_64_global_filter_size;
extern const struct sock_filter mips_filter[];
extern const size_t mips_filter_size;
+extern const struct sock_filter mips_global_filter[];
+extern const size_t mips_global_filter_size;
extern const struct sock_filter mips64_filter[];
extern const size_t mips64_filter_size;
+extern const struct sock_filter mips64_global_filter[];
+extern const size_t mips64_global_filter_size;
#endif
diff --git a/libc/seccomp/seccomp_policy.cpp b/libc/seccomp/seccomp_policy.cpp
index fe83af0..19ef299 100644
--- a/libc/seccomp/seccomp_policy.cpp
+++ b/libc/seccomp/seccomp_policy.cpp
@@ -34,9 +34,13 @@
#define PRIMARY_ARCH AUDIT_ARCH_AARCH64
static const struct sock_filter* primary_filter = arm64_filter;
static const size_t primary_filter_size = arm64_filter_size;
+static const struct sock_filter* primary_global_filter = arm64_global_filter;
+static const size_t primary_global_filter_size = arm64_global_filter_size;
#define SECONDARY_ARCH AUDIT_ARCH_ARM
static const struct sock_filter* secondary_filter = arm_filter;
static const size_t secondary_filter_size = arm_filter_size;
+static const struct sock_filter* secondary_global_filter = arm_global_filter;
+static const size_t secondary_global_filter_size = arm_global_filter_size;
#elif defined __i386__ || defined __x86_64__
@@ -44,9 +48,13 @@
#define PRIMARY_ARCH AUDIT_ARCH_X86_64
static const struct sock_filter* primary_filter = x86_64_filter;
static const size_t primary_filter_size = x86_64_filter_size;
+static const struct sock_filter* primary_global_filter = x86_64_global_filter;
+static const size_t primary_global_filter_size = x86_64_global_filter_size;
#define SECONDARY_ARCH AUDIT_ARCH_I386
static const struct sock_filter* secondary_filter = x86_filter;
static const size_t secondary_filter_size = x86_filter_size;
+static const struct sock_filter* secondary_global_filter = x86_global_filter;
+static const size_t secondary_global_filter_size = x86_global_filter_size;
#elif defined __mips__ || defined __mips64__
@@ -54,9 +62,13 @@
#define PRIMARY_ARCH AUDIT_ARCH_MIPSEL64
static const struct sock_filter* primary_filter = mips64_filter;
static const size_t primary_filter_size = mips64_filter_size;
+static const struct sock_filter* primary_global_filter = mips64_global_filter;
+static const size_t primary_global_filter_size = mips64_global_filter_size;
#define SECONDARY_ARCH AUDIT_ARCH_MIPSEL
static const struct sock_filter* secondary_filter = mips_filter;
static const size_t secondary_filter_size = mips_filter_size;
+static const struct sock_filter* secondary_global_filter = mips_global_filter;
+static const size_t secondary_global_filter_size = mips_global_filter_size;
#else
#error No architecture was defined!
@@ -119,9 +131,23 @@
return true;
}
-bool set_seccomp_filter() {
+bool _set_seccomp_filter(bool global) {
+ const sock_filter *p, *s;
+ size_t p_size, s_size;
filter f;
+ if (global) {
+ p = primary_global_filter;
+ p_size = primary_global_filter_size;
+ s = secondary_global_filter;
+ s_size = secondary_global_filter_size;
+ } else {
+ p = primary_filter;
+ p_size = primary_filter_size;
+ s = secondary_filter;
+ s_size = secondary_filter_size;
+ }
+
#ifdef DUAL_ARCH
// Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
// jump that must be changed to point to the start of the 32-bit policy
@@ -133,8 +159,8 @@
ExamineSyscall(f);
- for (size_t i = 0; i < primary_filter_size; ++i) {
- f.push_back(primary_filter[i]);
+ for (size_t i = 0; i < p_size; ++i) {
+ f.push_back(p[i]);
}
Disallow(f);
@@ -145,8 +171,8 @@
ExamineSyscall(f);
- for (size_t i = 0; i < secondary_filter_size; ++i) {
- f.push_back(secondary_filter[i]);
+ for (size_t i = 0; i < s_size; ++i) {
+ f.push_back(s[i]);
}
Disallow(f);
#endif
@@ -154,6 +180,14 @@
return install_filter(f);
}
+bool set_seccomp_filter() {
+ return _set_seccomp_filter(false);
+}
+
+bool set_global_seccomp_filter() {
+ return _set_seccomp_filter(true);
+}
+
void get_seccomp_filter(const sock_filter*& filter, size_t& filter_size) {
#if defined __aarch64__ || defined __x86_64__ || defined __mips64__
filter = primary_filter;
diff --git a/libc/seccomp/x86_64_global_policy.cpp b/libc/seccomp/x86_64_global_policy.cpp
new file mode 100644
index 0000000..71be1c1
--- /dev/null
+++ b/libc/seccomp/x86_64_global_policy.cpp
@@ -0,0 +1,97 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter x86_64_global_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 86),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 175, 43, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 79, 21, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 35, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 79, 78), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 78, 77), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 6, 77, 76), //fstat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 32, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 21, 74, 73), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|rt_sigreturn|ioctl|pread64|pwrite64|readv|writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 29, 73, 72), //sched_yield|mremap|msync|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 72, 71), //dup
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 38, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 37, 68, 67), //nanosleep|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 67, 66), //setitimer|getpid|sendfile|socket|connect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 66, 65), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 72, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 64, 64, 63), //vfork|execve|exit|wait4|kill|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 78, 63, 62), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 82, 58, 57), //getcwd|chdir|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 92, 57, 56), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 56, 55), //fchown
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 135, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 112, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 111, 53, 52), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid|syslog|getgid|setuid|setgid|geteuid|getegid|setpgid|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 132, 52, 51), //setsid|setreuid|setregid|getgroups|setgroups|setresuid|getresuid|setresgid|getresgid|getpgid|setfsuid|setfsgid|getsid|capget|capset|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 51, 50), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 157, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 155, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 139, 47, 46), //statfs|fstatfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 153, 46, 45), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 156, 45, 44), //pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 43, 42), //prctl|arch_prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2|swapon
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 42, 41), //reboot|sethostname|setdomainname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 21, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 233, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 186, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 179, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 177, 36, 35), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 35, 34), //quotactl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 201, 34, 33), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 221, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 205, 31, 30), //futex|sched_setaffinity|sched_getaffinity
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 30, 29), //getdents64|set_tid_address|restart_syscall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 232, 29, 28), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 247, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 235, 25, 24), //epoll_ctl|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 24, 23), //waitid|add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 23, 22), //keyctl|ioprio_set|ioprio_get
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 257, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 21, 20), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 261, 20, 19), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 302, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 283, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 275, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 15, 14), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 279, 14, 13), //splice|tee|sync_file_range|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 13, 12), //utimensat|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 11, 10), //timerfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 10, 9), //fallocate|timerfd_settime|timerfd_gettime|accept4|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 305, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 303, 6, 5), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 312, 5, 4), //clock_adjtime|syncfs|sendmmsg|setns|getcpu|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 320, 4, 3), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 325, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 323, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 329, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t x86_64_global_filter_size = sizeof(x86_64_global_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/x86_global_policy.cpp b/libc/seccomp/x86_global_policy.cpp
new file mode 100644
index 0000000..36f4884
--- /dev/null
+++ b/libc/seccomp/x86_global_policy.cpp
@@ -0,0 +1,129 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter x86_global_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 118),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 59, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 111, 110), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 110, 109), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 108, 107), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 107, 106), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 104, 103), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 103, 102), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 101, 100), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 100, 99), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 96, 95), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 95, 94), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 93, 92), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 92, 91), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 89, 88), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 88, 87), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 87, 86), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 102, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 87, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 82, 81), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 81, 80), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 79, 78), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 78, 77), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 90, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 75, 74), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 74, 73), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 72, 71), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 71, 70), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 67, 66), //socketcall|syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 66, 65), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 64, 63), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 63, 62), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 60, 59), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 59, 58), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 58, 57), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 52, 51), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 51, 50), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 49, 48), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 48, 47), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 45, 44), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 44, 43), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 42, 41), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 41, 40), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 37, 36), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 36, 35), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 34, 33), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 33, 32), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 30, 29), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 29, 28), //fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 28, 27), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 288, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 287, 23, 22), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 22, 21), //keyctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 20, 19), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 19, 18), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 16, 15), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 15, 14), //splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 14, 13), //getcpu|epoll_pwait|utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 343, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 337, 10, 9), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 341, 9, 8), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 346, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 7, 6), //clock_adjtime|syncfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 6, 5), //setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 376, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 358, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 357, 3, 2), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 359, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t x86_global_filter_size = sizeof(x86_global_filter) / sizeof(struct sock_filter);
diff --git a/libc/stdio/fmemopen.cpp b/libc/stdio/fmemopen.cpp
new file mode 100644
index 0000000..9d8c41f
--- /dev/null
+++ b/libc/stdio/fmemopen.cpp
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (C) 2013 Pietro Cerutti <gahr@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "local.h"
+
+// See http://pubs.opengroup.org/onlinepubs/9699919799/functions/fmemopen.html
+// and http://man7.org/linux/man-pages/man3/fmemopen.3.html for documentation.
+
+struct fmemopen_cookie {
+ char* buf;
+ char* allocation;
+ size_t capacity;
+ size_t size;
+ size_t offset;
+ bool append;
+};
+
+static int fmemopen_read(void* cookie, char* buf, int n) {
+ fmemopen_cookie* ck = static_cast<fmemopen_cookie*>(cookie);
+
+ if (static_cast<size_t>(n) > ck->size - ck->offset) n = ck->size - ck->offset;
+
+ if (n > 0) {
+ memmove(buf, ck->buf + ck->offset, n);
+ ck->offset += n;
+ }
+ return n;
+}
+
+static int fmemopen_write(void* cookie, const char* buf, int n) {
+ fmemopen_cookie* ck = static_cast<fmemopen_cookie*>(cookie);
+
+ // We don't need to add the trailing NUL if there's already a trailing NUL
+ // in the data we're writing.
+ size_t space_for_null = (n > 0 && buf[n - 1] != '\0') ? 1 : 0;
+
+ // Undo any seeking/reading on an append-only stream.
+ if (ck->append) ck->offset = ck->size;
+
+ // How much can we actually fit?
+ if (static_cast<size_t>(n) + space_for_null > ck->capacity - ck->offset) {
+ n = ck->capacity - ck->offset - space_for_null;
+ // Give up if we don't even have room for one byte of userdata.
+ if (n <= 0) {
+ errno = ENOSPC;
+ return -1;
+ }
+ }
+
+ if (n > 0) {
+ memmove(ck->buf + ck->offset, buf, n);
+ ck->offset += n;
+ // Is this the furthest we've ever been?
+ if (ck->offset >= ck->size) {
+ if (buf[n - 1] != '\0') ck->buf[ck->offset] = '\0';
+ ck->size = ck->offset;
+ }
+ }
+ return n;
+}
+
+static fpos_t fmemopen_seek(void* cookie, fpos_t offset, int whence) {
+ fmemopen_cookie* ck = static_cast<fmemopen_cookie*>(cookie);
+
+ if (whence == SEEK_SET && (offset >= 0 && static_cast<size_t>(offset) <= ck->capacity)) {
+ return (ck->offset = offset);
+ } else if (whence == SEEK_CUR && (ck->offset + offset <= ck->capacity)) {
+ return (ck->offset += offset);
+ } else if (whence == SEEK_END && (offset <= 0 && static_cast<size_t>(-offset) <= ck->size)) {
+ return (ck->offset = ck->size + offset);
+ }
+ errno = EINVAL;
+ return -1;
+}
+
+static int fmemopen_close(void* cookie) {
+ fmemopen_cookie* ck = static_cast<fmemopen_cookie*>(cookie);
+ free(ck->allocation);
+ free(ck);
+ return 0;
+}
+
+FILE* fmemopen(void* buf, size_t capacity, const char* mode) {
+ int flags;
+ if (__sflags(mode, &flags) == 0) {
+ errno = EINVAL;
+ return nullptr;
+ }
+
+ fmemopen_cookie* ck = static_cast<fmemopen_cookie*>(calloc(sizeof(fmemopen_cookie), 1));
+ if (ck == nullptr) return nullptr;
+
+ ck->buf = static_cast<char*>(buf);
+ ck->capacity = capacity;
+
+ if (ck->buf == nullptr) ck->buf = ck->allocation = static_cast<char*>(calloc(capacity, 1));
+ if (ck->buf == nullptr) {
+ free(ck);
+ return nullptr;
+ }
+
+ FILE* fp = funopen(ck,
+ (flags & O_WRONLY) ? nullptr : fmemopen_read,
+ (flags & O_RDONLY) ? nullptr : fmemopen_write,
+ fmemopen_seek,
+ fmemopen_close);
+ if (fp == nullptr) {
+ fmemopen_close(ck);
+ return nullptr;
+ }
+
+ if (mode[0] == 'a') {
+ ck->size = strnlen(ck->buf, ck->capacity);
+ ck->offset = ck->size;
+ ck->append = true;
+ } else if (mode[0] == 'r') {
+ ck->size = capacity;
+ ck->offset = 0;
+ } else if (mode[0] == 'w') {
+ ck->size = 0;
+ ck->offset = 0;
+ ck->buf[0] = '\0';
+ }
+
+ return fp;
+}
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 575a428..bf6a8f8 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -127,14 +127,15 @@
// Values for `__sFILE::_flags`.
#define __SLBF 0x0001 // Line buffered.
#define __SNBF 0x0002 // Unbuffered.
-// RD and WR are never simultaneously asserted: use _SRW instead.
-#define __SRD 0x0004 // OK to read.
-#define __SWR 0x0008 // OK to write.
-#define __SRW 0x0010 // Open for reading & writing.
+// __SRD and __SWR are mutually exclusive because they indicate what we did last.
+// If you want to know whether we were opened read-write, check __SRW instead.
+#define __SRD 0x0004 // Last operation was read.
+#define __SWR 0x0008 // Last operation was write.
+#define __SRW 0x0010 // Was opened for reading & writing.
#define __SEOF 0x0020 // Found EOF.
#define __SERR 0x0040 // Found error.
#define __SMBF 0x0080 // `_buf` is from malloc.
-#define __SAPP 0x0100 // fdopen()ed in append mode.
+// #define __SAPP 0x0100 --- historical (fdopen()ed in append mode).
#define __SSTR 0x0200 // This is an sprintf/snprintf string.
// #define __SOPT 0x0400 --- historical (do fseek() optimization).
// #define __SNPT 0x0800 --- historical (do not do fseek() optimization).
@@ -143,7 +144,7 @@
#define __SALC 0x4000 // Allocate string space dynamically.
#define __SIGN 0x8000 // Ignore this file in _fwalk.
-// TODO: remove remaining references to these obsolete flags.
+// TODO: remove remaining references to these obsolete flags (see above).
#define __SNPT 0
#define __SOPT 0
@@ -201,10 +202,10 @@
int __swhatbuf(FILE *, size_t *, int *);
wint_t __fgetwc_unlock(FILE *);
wint_t __ungetwc(wint_t, FILE *);
-int __vfprintf(FILE *, const char *, __va_list);
-int __svfscanf(FILE * __restrict, const char * __restrict, __va_list);
-int __vfwprintf(FILE * __restrict, const wchar_t * __restrict, __va_list);
-int __vfwscanf(FILE * __restrict, const wchar_t * __restrict, __va_list);
+int __vfprintf(FILE *, const char *, va_list);
+int __svfscanf(FILE *, const char *, va_list);
+int __vfwprintf(FILE *, const wchar_t *, va_list);
+int __vfwscanf(FILE *, const wchar_t *, va_list);
/*
* Return true if the given FILE cannot be written now.
@@ -224,15 +225,6 @@
_UB(fp)._base = NULL; \
}
-/*
- * test for an fgetln() buffer.
- */
-#define HASLB(fp) ((fp)->_lb._base != NULL)
-#define FREELB(fp) { \
- free((char *)(fp)->_lb._base); \
- (fp)->_lb._base = NULL; \
-}
-
#define FLOCKFILE(fp) if (!_EXT(fp)->_caller_handles_locking) flockfile(fp)
#define FUNLOCKFILE(fp) if (!_EXT(fp)->_caller_handles_locking) funlockfile(fp)
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index b0f5c60..4d6438b 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -68,14 +68,8 @@
_THREAD_PRIVATE_MUTEX(__sfp_mutex);
-// TODO: when we no longer have to support both clang and GCC, we can simplify all this.
-#define SBUF_INIT {0,0}
-#if defined(__LP64__)
-#define MBSTATE_T_INIT {{0},{0}}
-#else
-#define MBSTATE_T_INIT {{0}}
-#endif
-#define WCHAR_IO_DATA_INIT {MBSTATE_T_INIT,MBSTATE_T_INIT,{0},0,0}
+#define SBUF_INIT {}
+#define WCHAR_IO_DATA_INIT {}
static struct __sfileext __sFext[3] = {
{ SBUF_INIT, WCHAR_IO_DATA_INIT, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, false, __sseek64 },
@@ -132,6 +126,13 @@
return g;
}
+static inline void free_fgetln_buffer(FILE* fp) {
+ if (__predict_false(fp->_lb._base != nullptr)) {
+ free(fp->_lb._base);
+ fp->_lb._base = nullptr;
+ }
+}
+
/*
* Find a free FILE for fopen et al.
*/
@@ -205,11 +206,11 @@
}
FILE* fopen(const char* file, const char* mode) {
- int oflags;
- int flags = __sflags(mode, &oflags);
+ int mode_flags;
+ int flags = __sflags(mode, &mode_flags);
if (flags == 0) return nullptr;
- int fd = open(file, oflags, DEFFILEMODE);
+ int fd = open(file, mode_flags, DEFFILEMODE);
if (fd == -1) {
return nullptr;
}
@@ -221,41 +222,34 @@
return nullptr;
}
- // When opening in append mode, even though we use O_APPEND,
- // we need to seek to the end so that ftell() gets the right
- // answer. If the user then alters the seek pointer, or
- // the file extends, this will fail, but there is not much
- // we can do about this. (We could set __SAPP and check in
- // fseek and ftell.)
- // TODO: check in __sseek instead.
- if (oflags & O_APPEND) __sseek64(fp, 0, SEEK_END);
-
+ // For append mode, even though we use O_APPEND, we need to seek to the end now.
+ if ((mode_flags & O_APPEND) != 0) __sseek64(fp, 0, SEEK_END);
return fp;
}
__strong_alias(fopen64, fopen);
FILE* fdopen(int fd, const char* mode) {
- int oflags;
- int flags = __sflags(mode, &oflags);
+ int mode_flags;
+ int flags = __sflags(mode, &mode_flags);
if (flags == 0) return nullptr;
// Make sure the mode the user wants is a subset of the actual mode.
- int fdflags = fcntl(fd, F_GETFL, 0);
- if (fdflags < 0) return nullptr;
- int tmp = fdflags & O_ACCMODE;
- if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
+ int fd_flags = fcntl(fd, F_GETFL, 0);
+ if (fd_flags == -1) return nullptr;
+ int tmp = fd_flags & O_ACCMODE;
+ if (tmp != O_RDWR && (tmp != (mode_flags & O_ACCMODE))) {
errno = EINVAL;
return nullptr;
}
- // If opened for appending, but underlying descriptor does not have
- // O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
- // end before each write.
- // TODO: use fcntl(2) to set O_APPEND instead.
- if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) flags |= __SAPP;
+ // Make sure O_APPEND is set on the underlying fd if our mode has 'a'.
+ // POSIX says we just take the current offset of the underlying fd.
+ if ((mode_flags & O_APPEND) && !(fd_flags & O_APPEND)) {
+ if (fcntl(fd, F_SETFL, fd_flags | O_APPEND) == -1) return nullptr;
+ }
- // If close-on-exec was requested, then turn it on if not already.
- if ((oflags & O_CLOEXEC) && !((tmp = fcntl(fd, F_GETFD)) & FD_CLOEXEC)) {
+ // Make sure O_CLOEXEC is set on the underlying fd if our mode has 'x'.
+ if ((mode_flags & O_CLOEXEC) && !((tmp = fcntl(fd, F_GETFD)) & FD_CLOEXEC)) {
fcntl(fd, F_SETFD, tmp | FD_CLOEXEC);
}
@@ -267,8 +261,8 @@
// all possible, no matter what.
// TODO: rewrite this mess completely.
FILE* freopen(const char* file, const char* mode, FILE* fp) {
- int oflags;
- int flags = __sflags(mode, &oflags);
+ int mode_flags;
+ int flags = __sflags(mode, &mode_flags);
if (flags == 0) {
fclose(fp);
return nullptr;
@@ -300,13 +294,13 @@
}
// Get a new descriptor to refer to the new file.
- int fd = open(file, oflags, DEFFILEMODE);
+ int fd = open(file, mode_flags, DEFFILEMODE);
if (fd < 0 && isopen) {
// If out of fd's close the old one and try again.
if (errno == ENFILE || errno == EMFILE) {
(*fp->_close)(fp->_cookie);
isopen = 0;
- fd = open(file, oflags, DEFFILEMODE);
+ fd = open(file, mode_flags, DEFFILEMODE);
}
}
@@ -326,7 +320,7 @@
if (HASUB(fp)) FREEUB(fp);
_UB(fp)._size = 0;
WCIO_FREE(fp);
- if (HASLB(fp)) FREELB(fp);
+ free_fgetln_buffer(fp);
fp->_lb._size = 0;
if (fd < 0) { // Did not get it after all.
@@ -339,7 +333,7 @@
// to maintain the descriptor. Various C library routines (perror)
// assume stderr is always fd STDERR_FILENO, even if being freopen'd.
if (wantfd >= 0 && fd != wantfd) {
- if (dup3(fd, wantfd, oflags & O_CLOEXEC) >= 0) {
+ if (dup3(fd, wantfd, mode_flags & O_CLOEXEC) >= 0) {
close(fd);
fd = wantfd;
}
@@ -360,13 +354,8 @@
fp->_close = __sclose;
_EXT(fp)->_seek64 = __sseek64;
- // When opening in append mode, even though we use O_APPEND,
- // we need to seek to the end so that ftell() gets the right
- // answer. If the user then alters the seek pointer, or
- // the file extends, this will fail, but there is not much
- // we can do about this. (We could set __SAPP and check in
- // fseek and ftell.)
- if (oflags & O_APPEND) __sseek64(fp, 0, SEEK_END);
+ // For append mode, even though we use O_APPEND, we need to seek to the end now.
+ if ((mode_flags & O_APPEND) != 0) __sseek64(fp, 0, SEEK_END);
return fp;
}
__strong_alias(freopen64, freopen);
@@ -386,7 +375,7 @@
}
if (fp->_flags & __SMBF) free(fp->_bf._base);
if (HASUB(fp)) FREEUB(fp);
- if (HASLB(fp)) FREELB(fp);
+ free_fgetln_buffer(fp);
// Poison this FILE so accesses after fclose will be obvious.
fp->_file = -1;
@@ -445,12 +434,6 @@
int __swrite(void* cookie, const char* buf, int n) {
FILE* fp = reinterpret_cast<FILE*>(cookie);
- if (fp->_flags & __SAPP) {
- // The FILE* is in append mode, but the underlying fd doesn't have O_APPEND set.
- // We need to seek manually.
- // TODO: use fcntl(2) to set O_APPEND in fdopen(3) instead?
- TEMP_FAILURE_RETRY(lseek64(fp->_file, 0, SEEK_END));
- }
return TEMP_FAILURE_RETRY(write(fp->_file, buf, n));
}
@@ -489,6 +472,7 @@
static off64_t __ftello64_unlocked(FILE* fp) {
// Find offset of underlying I/O object, then adjust for buffered bytes.
__sflush(fp); // May adjust seek offset on append stream.
+
off64_t result = __seek_unlocked(fp, 0, SEEK_CUR);
if (result == -1) {
return -1;
diff --git a/libc/stdio/stdio_ext.cpp b/libc/stdio/stdio_ext.cpp
index ebc705c..8cf4f4b 100644
--- a/libc/stdio/stdio_ext.cpp
+++ b/libc/stdio/stdio_ext.cpp
@@ -39,17 +39,13 @@
return fp->_bf._size;
}
-/* For a _SRW stream, we don't know whether we last read or wrote.
int __freading(FILE* fp) {
- return (fp->_flags & _SRD) != 0 || ...;
+ return (fp->_flags & __SRD) != 0;
}
-*/
-/* For a _SRW stream, we don't know whether we last read or wrote.
-int __fwriting(FILE*) {
- return (fp->_flags & _SWR) != 0 || ...;
+int __fwriting(FILE* fp) {
+ return (fp->_flags & __SWR) != 0;
}
-*/
int __freadable(FILE* fp) {
return (fp->_flags & (__SRD|__SRW)) != 0;
diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py
index 631fd93..e40f3e3 100755
--- a/libc/tools/check-symbols-glibc.py
+++ b/libc/tools/check-symbols-glibc.py
@@ -186,14 +186,17 @@
# being implemented (fattach).
in_posix_and_glibc_but_actually_dead = set([
'a64l',
+ 'confstr',
'fattach',
'fdetach',
+ 'gethostid',
'getmsg',
'getpmsg',
'isastream',
'l64a',
'putmsg',
'putpmsg',
+ 'ulimit',
])
posix = posix - in_posix_and_glibc_but_actually_dead
diff --git a/libc/tools/generate-NOTICE.py b/libc/tools/generate-NOTICE.py
index 6573644..d40891c 100755
--- a/libc/tools/generate-NOTICE.py
+++ b/libc/tools/generate-NOTICE.py
@@ -14,17 +14,33 @@
import tarfile
import tempfile
-def IsUninteresting(path):
- path = path.lower()
- if path.endswith(".mk") or path.endswith(".py") or path.endswith(".pyc") or path.endswith(".txt") or path.endswith(".3") or path.endswith(".swp"):
- return True
- if path.endswith("/notice") or path.endswith("/readme") or path.endswith("/caveats"):
- return True
- if path.endswith("/tzdata") or path.endswith("/zoneinfo/generate"):
- return True
- return False
+VERBOSE = False
-def IsAutoGenerated(content):
+def warn(s):
+ sys.stderr.write("warning: %s\n" % s)
+
+def warn_verbose(s):
+ if VERBOSE:
+ warn(s)
+
+def is_interesting(path):
+ path = path.lower()
+ uninteresting_extensions = [
+ ".bp",
+ ".map",
+ ".mk",
+ ".py",
+ ".pyc",
+ ".swp",
+ ".txt",
+ ]
+ if os.path.splitext(path)[1] in uninteresting_extensions:
+ return False
+ if path.endswith("/notice") or path.endswith("/readme"):
+ return False
+ return True
+
+def is_auto_generated(content):
if "Generated by gensyscalls.py" in content or "generated by genserv.py" in content:
return True
if "This header was automatically generated from a Linux kernel header" in content:
@@ -33,7 +49,7 @@
copyrights = set()
-def ExtractCopyrightAt(lines, i):
+def extract_copyright_at(lines, i):
hash = lines[i].startswith("#")
# Do we need to back up to find the start of the copyright header?
@@ -100,13 +116,42 @@
return i
-args = sys.argv[1:]
-if len(args) == 0:
- args = [ "." ]
-for arg in args:
- sys.stderr.write('Searching for source files in "%s"...\n' % arg)
+def do_file(path):
+ with open(path, "r") as the_file:
+ try:
+ content = open(path, "r").read().decode("utf-8")
+ except UnicodeDecodeError:
+ warn("bad UTF-8 in %s" % path)
+ content = open(path, "r").read().decode("iso-8859-1")
+ lines = content.split("\n")
+
+ if len(lines) <= 4:
+ warn_verbose("ignoring short file %s" % path)
+ return
+
+ if is_auto_generated(content):
+ warn_verbose("ignoring auto-generated file %s" % path)
+ return
+
+ if not "Copyright" in content:
+ if "public domain" in content.lower():
+ warn("ignoring public domain file %s" % path)
+ return
+ warn('no copyright notice found in "%s" (%d lines)' % (path, len(lines)))
+ return
+
+ # Manually iterate because extract_copyright_at tells us how many lines to skip.
+ i = 0
+ while i < len(lines):
+ if "Copyright" in lines[i] and not "@(#) Copyright" in lines[i]:
+ i = extract_copyright_at(lines, i)
+ else:
+ i += 1
+
+
+def do_dir(path):
for directory, sub_directories, filenames in os.walk(arg):
if ".git" in sub_directories:
sub_directories.remove(".git")
@@ -114,45 +159,24 @@
for filename in sorted(filenames):
path = os.path.join(directory, filename)
- if IsUninteresting(path):
- #print "ignoring uninteresting file %s" % path
- continue
+ if is_interesting(path):
+ do_file(path)
- try:
- content = open(path, 'r').read().decode('utf-8')
- except:
- sys.stderr.write('warning: bad UTF-8 in %s\n' % path)
- content = open(path, 'r').read().decode('iso-8859-1')
- lines = content.split("\n")
+args = sys.argv[1:]
+if len(args) == 0:
+ args = [ "." ]
- if len(lines) <= 4:
- #print "ignoring short file %s" % path
- continue
-
- if IsAutoGenerated(content):
- #print "ignoring auto-generated file %s" % path
- continue
-
- if not "Copyright" in content:
- if "public domain" in content.lower():
- #print "ignoring public domain file %s" % path
- continue
- sys.stderr.write('warning: no copyright notice found in "%s" (%d lines)\n' % (path, len(lines)))
- continue
-
- i = 0
- while i < len(lines):
- if "Copyright" in lines[i] and not "@(#) Copyright" in lines[i]:
- i = ExtractCopyrightAt(lines, i)
- i += 1
-
- #print path
+for arg in args:
+ if os.path.isdir(arg):
+ do_dir(arg)
+ else:
+ do_file(arg)
for copyright in sorted(copyrights):
- print copyright.encode('utf-8')
+ print copyright.encode("utf-8")
print
- print '-------------------------------------------------------------------'
+ print "-------------------------------------------------------------------"
print
sys.exit(0)
diff --git a/libc/tools/genseccomp.py b/libc/tools/genseccomp.py
index 79968ae..f3a232e 100755
--- a/libc/tools/genseccomp.py
+++ b/libc/tools/genseccomp.py
@@ -26,7 +26,7 @@
self.names.append(name)
-def get_names(syscall_files, architecture):
+def get_names(syscall_files, architecture, global_policy):
syscall_lists = []
for syscall_file in syscall_files:
parser = SysCallsTxtParser()
@@ -34,6 +34,11 @@
syscall_lists.append(parser.syscalls)
bionic, whitelist, blacklist = syscall_lists[0], syscall_lists[1], syscall_lists[2]
+ if global_policy:
+ global_whitelist = syscall_lists[-1]
+ else:
+ global_whitelist = []
+
for x in blacklist:
if not x in bionic:
raise RuntimeError("Blacklist item not in bionic - aborting " + str(x))
@@ -42,7 +47,7 @@
raise RuntimeError("Blacklist item in whitelist - aborting " + str(x))
bionic_minus_blacklist = [x for x in bionic if x not in blacklist]
- syscalls = bionic_minus_blacklist + whitelist
+ syscalls = bionic_minus_blacklist + whitelist + global_whitelist
# Select only elements matching required architecture
syscalls = [x for x in syscalls if architecture in x and x[architecture]]
@@ -170,7 +175,8 @@
return bpf
-def convert_bpf_to_output(bpf, architecture):
+def convert_bpf_to_output(bpf, architecture, global_policy):
+ suffix = "global_" if global_policy else ""
header = textwrap.dedent("""\
// Autogenerated file - edit at your peril!!
@@ -178,24 +184,25 @@
#include <errno.h>
#include "seccomp_bpfs.h"
- const sock_filter {architecture}_filter[] = {{
- """).format(architecture=architecture)
+ const sock_filter {architecture}_{suffix}filter[] = {{
+ """).format(architecture=architecture,suffix=suffix)
footer = textwrap.dedent("""\
}};
- const size_t {architecture}_filter_size = sizeof({architecture}_filter) / sizeof(struct sock_filter);
- """).format(architecture=architecture)
+ const size_t {architecture}_{suffix}filter_size = sizeof({architecture}_{suffix}filter) / sizeof(struct sock_filter);
+ """).format(architecture=architecture,suffix=suffix)
return header + "\n".join(bpf) + footer
-def construct_bpf(syscall_files, architecture, header_dir, extra_switches):
- names = get_names(syscall_files, architecture)
+def construct_bpf(syscall_files, architecture, header_dir, extra_switches,
+ global_policy):
+ names = get_names(syscall_files, architecture, global_policy)
syscalls = convert_names_to_NRs(names, header_dir, extra_switches)
ranges = convert_NRs_to_ranges(syscalls)
bpf = convert_ranges_to_bpf(ranges)
- return convert_bpf_to_output(bpf, architecture)
+ return convert_bpf_to_output(bpf, architecture, global_policy)
ANDROID_SYSCALL_FILES = ["SYSCALLS.TXT",
@@ -216,15 +223,18 @@
os.chdir(os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc"))
-def main():
- set_dir()
+def gen_policy(global_policy):
+ if global_policy:
+ ANDROID_SYSCALL_FILES.append("SECCOMP_WHITELIST_GLOBAL.TXT")
+
for arch, header_path, switches in POLICY_CONFIGS:
files = [open(filename) for filename in ANDROID_SYSCALL_FILES]
- output = construct_bpf(files, arch, header_path, switches)
+ output = construct_bpf(files, arch, header_path, switches, global_policy)
# And output policy
existing = ""
- output_path = "seccomp/{}_policy.cpp".format(arch)
+ global_string = "_global" if global_policy else ""
+ output_path = "seccomp/{}{}_policy.cpp".format(arch, global_string)
if os.path.isfile(output_path):
existing = open(output_path).read()
if output == existing:
@@ -234,5 +244,11 @@
output_file.write(output)
print "Generated file " + output_path
+
+def main():
+ set_dir()
+ gen_policy(False)
+ gen_policy(True)
+
if __name__ == "__main__":
main()
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index ab7c247..e6240a1 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -568,7 +568,7 @@
# Collect the set of all syscalls for all architectures.
syscalls = set()
- pattern = re.compile(r'^\s*#\s*define\s*__NR_([a-z]\S+)')
+ pattern = re.compile(r'^\s*#\s*define\s*__NR_([a-z_]\S+)')
for unistd_h in ["kernel/uapi/asm-generic/unistd.h",
"kernel/uapi/asm-arm/asm/unistd.h",
"kernel/uapi/asm-arm/asm/unistd-common.h",
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/realpath.c b/libc/upstream-freebsd/lib/libc/stdlib/realpath.c
index 914ecc9..c4bd953 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/realpath.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/realpath.c
@@ -48,7 +48,7 @@
* in which case the path which caused trouble is left in (resolved).
*/
char *
-realpath(const char * __restrict path, char * __restrict resolved) __overloadable
+realpath(const char * __restrict path, char * __restrict resolved)
{
struct stat sb;
char *p, *q, *s;
diff --git a/libc/upstream-openbsd/lib/libc/compat-43/killpg.c b/libc/upstream-freebsd/lib/libc/string/wcsstr.c
similarity index 65%
rename from libc/upstream-openbsd/lib/libc/compat-43/killpg.c
rename to libc/upstream-freebsd/lib/libc/string/wcsstr.c
index 75b1ad9..ce598a6 100644
--- a/libc/upstream-openbsd/lib/libc/compat-43/killpg.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsstr.c
@@ -1,6 +1,9 @@
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,19 +30,34 @@
* SUCH DAMAGE.
*/
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strstr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <wchar.h>
/*
- * Backwards-compatible killpg().
+ * Find the first occurrence of find in s.
*/
-int
-killpg(pid_t pgid, int sig)
+wchar_t *
+wcsstr(const wchar_t * __restrict s, const wchar_t * __restrict find)
{
- if (pgid == 1) {
- errno = ESRCH;
- return (-1);
+ wchar_t c, sc;
+ size_t len;
+
+ if ((c = *find++) != L'\0') {
+ len = wcslen(find);
+ do {
+ do {
+ if ((sc = *s++) == L'\0')
+ return (NULL);
+ } while (sc != c);
+ } while (wcsncmp(s, find, len) != 0);
+ s--;
}
- return (kill(-pgid, sig));
+ return ((wchar_t *)s);
}
diff --git a/libc/upstream-openbsd/lib/libc/string/wmemcpy.c b/libc/upstream-freebsd/lib/libc/string/wmemcpy.c
similarity index 84%
rename from libc/upstream-openbsd/lib/libc/string/wmemcpy.c
rename to libc/upstream-freebsd/lib/libc/string/wmemcpy.c
index cf02ab9..c10770c 100644
--- a/libc/upstream-openbsd/lib/libc/string/wmemcpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemcpy.c
@@ -1,6 +1,3 @@
-/* $OpenBSD: wmemcpy.c,v 1.4 2015/09/12 16:23:14 guenther Exp $ */
-/* $NetBSD: wmemcpy.c,v 1.2 2001/01/03 14:29:37 lukem Exp $ */
-
/*-
* Copyright (c)1999 Citrus Project,
* All rights reserved.
@@ -29,13 +26,19 @@
* citrus Id: wmemcpy.c,v 1.2 2000/12/20 14:08:31 itojun Exp
*/
+#include <sys/cdefs.h>
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wmemcpy.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
+#endif /* LIBC_SCCS and not lint */
+#endif
+__FBSDID("$FreeBSD$");
+
#include <string.h>
#include <wchar.h>
wchar_t *
-wmemcpy(wchar_t *d, const wchar_t *s, size_t n)
+wmemcpy(wchar_t * __restrict d, const wchar_t * __restrict s, size_t n)
{
-
return (wchar_t *)memcpy(d, s, n * sizeof(wchar_t));
}
-DEF_STRONG(wmemcpy);
diff --git a/libc/upstream-netbsd/android/include/netbsd-compat.h b/libc/upstream-netbsd/android/include/netbsd-compat.h
index 45b974a..af5ae29 100644
--- a/libc/upstream-netbsd/android/include/netbsd-compat.h
+++ b/libc/upstream-netbsd/android/include/netbsd-compat.h
@@ -44,4 +44,8 @@
#include <stddef.h>
int reallocarr(void*, size_t, size_t);
+/* Use appropriate shell depending on process's executable. */
+__LIBC_HIDDEN__ extern const char* __bionic_get_shell_path();
+#define _PATH_BSHELL __bionic_get_shell_path()
+
#endif
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index 9b16da7..d831435 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -40,6 +40,7 @@
/* Ignore all DEF_STRONG/DEF_WEAK in OpenBSD. */
#define DEF_STRONG(sym)
#define DEF_WEAK(sym)
+#define __weak_alias __strong_alias
/* Ignore all __warn_references in OpenBSD. */
#define __warn_references(sym,msg)
@@ -70,6 +71,10 @@
*/
#define _PATH_TMP "/data/local/tmp/"
+/* Use appropriate shell depending on process's executable. */
+__LIBC_HIDDEN__ extern const char* __bionic_get_shell_path();
+#define _PATH_BSHELL __bionic_get_shell_path()
+
/* We have OpenBSD's getentropy_linux.c, but we don't mention getentropy in any header. */
__LIBC_HIDDEN__ extern int getentropy(void*, size_t);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fmemopen.c b/libc/upstream-openbsd/lib/libc/stdio/fmemopen.c
deleted file mode 100644
index 00c2764..0000000
--- a/libc/upstream-openbsd/lib/libc/stdio/fmemopen.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* $OpenBSD: fmemopen.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ */
-
-/*
- * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
- * Copyright (c) 2009 Ted Unangst
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "local.h"
-
-struct state {
- char *string; /* actual stream */
- size_t pos; /* current position */
- size_t size; /* allocated size */
- size_t len; /* length of the data */
- int update; /* open for update */
-};
-
-static int
-fmemopen_read(void *v, char *b, int l)
-{
- struct state *st = v;
- int i;
-
- for (i = 0; i < l && i + st->pos < st->len; i++)
- b[i] = st->string[st->pos + i];
- st->pos += i;
-
- return (i);
-}
-
-static int
-fmemopen_write(void *v, const char *b, int l)
-{
- struct state *st = v;
- int i;
-
- for (i = 0; i < l && i + st->pos < st->size; i++)
- st->string[st->pos + i] = b[i];
- st->pos += i;
-
- if (st->pos >= st->len) {
- st->len = st->pos;
-
- if (st->len < st->size)
- st->string[st->len] = '\0';
- else if (!st->update)
- st->string[st->size - 1] = '\0';
- }
-
- return (i);
-}
-
-static fpos_t
-fmemopen_seek(void *v, fpos_t off, int whence)
-{
- struct state *st = v;
- ssize_t base = 0;
-
- switch (whence) {
- case SEEK_SET:
- break;
- case SEEK_CUR:
- base = st->pos;
- break;
- case SEEK_END:
- base = st->len;
- break;
- }
-
- if (off > st->size - base || off < -base) {
- errno = EOVERFLOW;
- return (-1);
- }
-
- st->pos = base + off;
-
- return (st->pos);
-}
-
-static int
-fmemopen_close(void *v)
-{
- free(v);
-
- return (0);
-}
-
-static int
-fmemopen_close_free(void *v)
-{
- struct state *st = v;
-
- free(st->string);
- free(st);
-
- return (0);
-}
-
-FILE *
-fmemopen(void *buf, size_t size, const char *mode)
-{
- struct state *st;
- FILE *fp;
- int flags, oflags;
-
- if (size == 0) {
- errno = EINVAL;
- return (NULL);
- }
-
- if ((flags = __sflags(mode, &oflags)) == 0) {
- errno = EINVAL;
- return (NULL);
- }
-
- if (buf == NULL && ((oflags & O_RDWR) == 0)) {
- errno = EINVAL;
- return (NULL);
- }
-
- if ((st = malloc(sizeof(*st))) == NULL)
- return (NULL);
-
- if ((fp = __sfp()) == NULL) {
- free(st);
- return (NULL);
- }
-
- st->pos = 0;
- st->len = (oflags & O_WRONLY) ? 0 : size;
- st->size = size;
- st->update = oflags & O_RDWR;
-
- if (buf == NULL) {
- if ((st->string = malloc(size)) == NULL) {
- free(st);
- fp->_flags = 0;
- return (NULL);
- }
- *st->string = '\0';
- } else {
- st->string = (char *)buf;
-
- if (oflags & O_TRUNC)
- *st->string = '\0';
-
- if (oflags & O_APPEND) {
- char *p;
-
- if ((p = memchr(st->string, '\0', size)) != NULL)
- st->pos = st->len = (p - st->string);
- else
- st->pos = st->len = size;
- }
- }
-
- fp->_flags = (short)flags;
- fp->_file = -1;
- fp->_cookie = (void *)st;
- fp->_read = (flags & __SWR) ? NULL : fmemopen_read;
- fp->_write = (flags & __SRD) ? NULL : fmemopen_write;
- fp->_seek = fmemopen_seek;
- fp->_close = (buf == NULL) ? fmemopen_close_free : fmemopen_close;
-
- return (fp);
-}
-DEF_WEAK(fmemopen);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/strtoimax.c b/libc/upstream-openbsd/lib/libc/stdlib/strtoimax.c
index 2fc04e4..74e3556 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/strtoimax.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/strtoimax.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strtoimax.c,v 1.2 2014/09/13 20:10:12 schwarze Exp $ */
+/* $OpenBSD: strtoimax.c,v 1.4 2017/07/06 16:23:11 millert Exp $ */
/*
* Copyright (c) 1992 The Regents of the University of California.
* All rights reserved.
@@ -74,8 +74,8 @@
if (c == '+')
c = *s++;
}
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
+ if ((base == 0 || base == 16) && c == '0' &&
+ (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
c = s[1];
s += 2;
base = 16;
@@ -148,3 +148,4 @@
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
+DEF_STRONG(strtoimax);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/strtol.c b/libc/upstream-openbsd/lib/libc/stdlib/strtol.c
index 86cec35..599d235 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/strtol.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/strtol.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strtol.c,v 1.10 2014/09/13 20:10:12 schwarze Exp $ */
+/* $OpenBSD: strtol.c,v 1.12 2017/07/06 16:23:11 millert Exp $ */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -75,8 +75,8 @@
if (c == '+')
c = *s++;
}
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
+ if ((base == 0 || base == 16) && c == '0' &&
+ (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
c = s[1];
s += 2;
base = 16;
@@ -148,3 +148,4 @@
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
+DEF_STRONG(strtol);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/strtoll.c b/libc/upstream-openbsd/lib/libc/stdlib/strtoll.c
index cf82c8e..d21a249 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/strtoll.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/strtoll.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strtoll.c,v 1.8 2014/09/13 20:10:12 schwarze Exp $ */
+/* $OpenBSD: strtoll.c,v 1.10 2017/07/06 16:23:11 millert Exp $ */
/*
* Copyright (c) 1992 The Regents of the University of California.
* All rights reserved.
@@ -77,8 +77,8 @@
if (c == '+')
c = *s++;
}
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
+ if ((base == 0 || base == 16) && c == '0' &&
+ (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
c = s[1];
s += 2;
base = 16;
@@ -151,5 +151,6 @@
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
+DEF_STRONG(strtoll);
-__strong_alias(strtoq, strtoll);
+__weak_alias(strtoq, strtoll);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/strtoul.c b/libc/upstream-openbsd/lib/libc/stdlib/strtoul.c
index 2aa41b7..6667bea 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/strtoul.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/strtoul.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strtoul.c,v 1.9 2014/09/13 20:10:12 schwarze Exp $ */
+/* $OpenBSD: strtoul.c,v 1.11 2017/07/06 16:23:11 millert Exp $ */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -69,8 +69,8 @@
if (c == '+')
c = *s++;
}
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
+ if ((base == 0 || base == 16) && c == '0' &&
+ (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
c = s[1];
s += 2;
base = 16;
@@ -107,3 +107,4 @@
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
+DEF_STRONG(strtoul);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/strtoull.c b/libc/upstream-openbsd/lib/libc/stdlib/strtoull.c
index 8464176..d7733e40 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/strtoull.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/strtoull.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strtoull.c,v 1.7 2014/09/13 20:10:12 schwarze Exp $ */
+/* $OpenBSD: strtoull.c,v 1.9 2017/07/06 16:23:11 millert Exp $ */
/*
* Copyright (c) 1992 The Regents of the University of California.
* All rights reserved.
@@ -71,8 +71,8 @@
if (c == '+')
c = *s++;
}
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
+ if ((base == 0 || base == 16) && c == '0' &&
+ (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
c = s[1];
s += 2;
base = 16;
@@ -109,5 +109,6 @@
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
+DEF_STRONG(strtoull);
-__strong_alias(strtouq, strtoull);
+__weak_alias(strtouq, strtoull);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/strtoumax.c b/libc/upstream-openbsd/lib/libc/stdlib/strtoumax.c
index c73f7e5..348184c 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/strtoumax.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/strtoumax.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strtoumax.c,v 1.2 2014/09/13 20:10:12 schwarze Exp $ */
+/* $OpenBSD: strtoumax.c,v 1.4 2017/07/06 16:23:11 millert Exp $ */
/*
* Copyright (c) 1992 The Regents of the University of California.
* All rights reserved.
@@ -68,8 +68,8 @@
if (c == '+')
c = *s++;
}
- if ((base == 0 || base == 16) &&
- c == '0' && (*s == 'x' || *s == 'X')) {
+ if ((base == 0 || base == 16) && c == '0' &&
+ (*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
c = s[1];
s += 2;
base = 16;
@@ -106,3 +106,4 @@
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
+DEF_STRONG(strtoumax);
diff --git a/libc/upstream-openbsd/lib/libc/string/wcsstr.c b/libc/upstream-openbsd/lib/libc/string/wcsstr.c
deleted file mode 100644
index 6a7b0da..0000000
--- a/libc/upstream-openbsd/lib/libc/string/wcsstr.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $OpenBSD: wcsstr.c,v 1.5 2015/10/01 02:32:07 guenther Exp $ */
-/* $NetBSD: wcsstr.c,v 1.3 2003/03/05 20:18:17 tshiozak Exp $ */
-
-/*-
- * Copyright (c)1999 Citrus Project,
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * citrus Id: wcsstr.c,v 1.2 2000/12/21 05:07:25 itojun Exp
- */
-
-#include <wchar.h>
-
-wchar_t *
-#ifdef WCSWCS
-wcswcs(const wchar_t *big, const wchar_t *little)
-#else
-wcsstr(const wchar_t *big, const wchar_t *little)
-#endif
-{
- const wchar_t *p;
- const wchar_t *q;
- const wchar_t *r;
-
- if (!*little) {
- return (wchar_t *)big;
- }
- if (wcslen(big) < wcslen(little))
- return NULL;
-
- p = big;
- q = little;
- while (*p) {
- q = little;
- r = p;
- while (*q) {
- if (*r != *q)
- break;
- q++;
- r++;
- }
- if (!*q) {
- return (wchar_t *)p;
- }
- p++;
- }
- return NULL;
-}
-#ifndef WCSWCS
-DEF_STRONG(wcsstr);
-#endif
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index 668f008..9fc9d23 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -34,11 +34,16 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_shadow_size; # future
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -48,4 +53,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index 8270fe9..bde6cab 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -33,11 +33,16 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_shadow_size; # future
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +52,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index a4c6483..d1f4ab8 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -33,11 +33,16 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_shadow_size; # future
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +52,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index 8270fe9..bde6cab 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -33,11 +33,16 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_shadow_size; # future
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +52,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index 8270fe9..bde6cab 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -33,11 +33,16 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_shadow_size; # future
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +52,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index 8270fe9..bde6cab 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -33,11 +33,16 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_shadow_size; # future
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +52,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index 8270fe9..bde6cab 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -33,11 +33,16 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_shadow_size; # future
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +52,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl_cfi.cpp b/libdl/libdl_cfi.cpp
index 8458564..483364f 100644
--- a/libdl/libdl_cfi.cpp
+++ b/libdl/libdl_cfi.cpp
@@ -38,6 +38,11 @@
return &shadow_base_storage.v;
}
+// Returns the size of the CFI shadow mapping, or 0 if CFI is not (yet) used in this process.
+extern "C" size_t __cfi_shadow_size() {
+ return shadow_base_storage.v != 0 ? CFIShadow::kShadowSize : 0;
+}
+
static uint16_t shadow_load(void* p) {
uintptr_t addr = reinterpret_cast<uintptr_t>(p);
uintptr_t ofs = CFIShadow::MemToShadowOffset(addr);
diff --git a/libm/Android.bp b/libm/Android.bp
index 8947f4d..75e8957 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -63,7 +63,6 @@
"upstream-freebsd/lib/msun/src/e_sinhf.c",
"upstream-freebsd/lib/msun/src/e_sqrt.c",
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
- "upstream-freebsd/lib/msun/src/imprecise.c",
"upstream-freebsd/lib/msun/src/k_cos.c",
"upstream-freebsd/lib/msun/src/k_cosf.c",
"upstream-freebsd/lib/msun/src/k_exp.c",
@@ -209,6 +208,7 @@
// Functionality not in the BSDs.
"significandl.c",
"sincos.c",
+ "fake_long_double.c",
// Modified versions of BSD code.
"signbit.c",
@@ -218,10 +218,6 @@
],
multilib: {
- lib32: {
- srcs: ["fake_long_double.c"],
- },
-
lib64: {
srcs: [
"upstream-freebsd/lib/msun/src/e_acosl.c",
diff --git a/libm/fake_long_double.c b/libm/fake_long_double.c
index 20148a3..fd983ed 100644
--- a/libm/fake_long_double.c
+++ b/libm/fake_long_double.c
@@ -17,12 +17,11 @@
#include <float.h>
#include <math.h>
-#ifndef __LP64__
-/*
- * The BSD "long double" functions are broken when sizeof(long double) == sizeof(double).
- * Android works around those cases by replacing the broken functions with our own trivial stubs
- * that call the regular "double" function.
- */
+#if !defined(__LP64__)
+
+// The BSD "long double" functions are broken when sizeof(long double) == sizeof(double).
+// Android works around those cases by replacing the broken functions with our own trivial stubs
+// that call the regular "double" function.
long double copysignl(long double a1, long double a2) { return copysign(a1, a2); }
long double fmaxl(long double a1, long double a2) { return fmax(a1, a2); }
@@ -40,3 +39,7 @@
long double roundl(long double a1) { return round(a1); }
#endif // __LP64__
+
+// FreeBSD doesn't have ld128 implementations of powl or tgammal, so both LP32 and LP64 need these.
+long double powl(long double x, long double y) { return pow(x, y); }
+long double tgammal(long double x) { return tgamma(x); }
diff --git a/libm/freebsd-compat.h b/libm/freebsd-compat.h
index a4dd6c2..ee41e45 100644
--- a/libm/freebsd-compat.h
+++ b/libm/freebsd-compat.h
@@ -28,7 +28,15 @@
#define __warn_references(sym,msg) /* ignored */
-/* digittoint is in BSD's <ctype.h>. */
+// digittoint is in BSD's <ctype.h>, but not ours, so we have a secret
+// implementation in libm. We reuse parts of libm in the NDK's
+// libandroid_support, where it's a static library, so we want all our
+// "hidden" functions start with a double underscore --- being HIDDEN
+// in the ELF sense is not sufficient.
+#define digittoint __libm_digittoint
int digittoint(char ch);
+// Similarly rename _scan_nan.
+#define _scan_nan __libm_scan_nan
+
#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/imprecise.c b/libm/upstream-freebsd/lib/msun/src/imprecise.c
deleted file mode 100644
index 08cd239..0000000
--- a/libm/upstream-freebsd/lib/msun/src/imprecise.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*-
- * Copyright (c) 2013 David Chisnall
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <float.h>
-#include <math.h>
-
-/*
- * If long double is not the same size as double, then these will lose
- * precision and we should emit a warning whenever something links against
- * them.
- */
-#if (LDBL_MANT_DIG > 53)
-#define WARN_IMPRECISE(x) \
- __warn_references(x, # x " has lower than advertised precision");
-#else
-#define WARN_IMPRECISE(x)
-#endif
-/*
- * Declare the functions as weak variants so that other libraries providing
- * real versions can override them.
- */
-#define DECLARE_WEAK(x)\
- __weak_reference(imprecise_## x, x);\
- WARN_IMPRECISE(x)
-
-long double
-imprecise_powl(long double x, long double y)
-{
-
- return pow(x, y);
-}
-DECLARE_WEAK(powl);
-
-#define DECLARE_IMPRECISE(f) \
- long double imprecise_ ## f ## l(long double v) { return f(v); }\
- DECLARE_WEAK(f ## l)
-
-DECLARE_IMPRECISE(tgamma);
diff --git a/linker/Android.bp b/linker/Android.bp
index efd91ac..fda7eb5 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -101,6 +101,12 @@
"-Werror",
],
+ product_variables: {
+ debuggable: {
+ cppflags: ["-DUSE_LD_CONFIG_FILE"],
+ },
+ },
+
cppflags: ["-Wold-style-cast"],
// we are going to link libc++_static manually because
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 8e7a141..59e4bac 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -66,6 +66,7 @@
#include "linker_reloc_iterators.h"
#include "linker_utils.h"
+#include "android-base/macros.h"
#include "android-base/strings.h"
#include "android-base/stringprintf.h"
#include "ziparchive/zip_archive.h"
@@ -83,6 +84,8 @@
static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
+static const char* const kLdConfigArchFilePath = "/system/etc/ld.config." ABI_STRING ".txt";
+
static const char* const kLdConfigFilePath = "/system/etc/ld.config.txt";
#if defined(__LP64__)
@@ -558,9 +561,10 @@
static LoadTask* create(const char* name,
soinfo* needed_by,
+ android_namespace_t* start_from,
std::unordered_map<const soinfo*, ElfReader>* readers_map) {
LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc();
- return new (ptr) LoadTask(name, needed_by, readers_map);
+ return new (ptr) LoadTask(name, needed_by, start_from, readers_map);
}
const char* get_name() const {
@@ -612,6 +616,11 @@
is_dt_needed_ = is_dt_needed;
}
+ // returns the namespace from where we need to start loading this.
+ const android_namespace_t* get_start_from() const {
+ return start_from_;
+ }
+
const ElfReader& get_elf_reader() const {
CHECK(si_ != nullptr);
return (*elf_readers_map_)[si_];
@@ -650,10 +659,11 @@
private:
LoadTask(const char* name,
soinfo* needed_by,
+ android_namespace_t* start_from,
std::unordered_map<const soinfo*, ElfReader>* readers_map)
: name_(name), needed_by_(needed_by), si_(nullptr),
fd_(-1), close_fd_(false), file_offset_(0), elf_readers_map_(readers_map),
- is_dt_needed_(false) {}
+ is_dt_needed_(false), start_from_(start_from) {}
~LoadTask() {
if (fd_ != -1 && close_fd_) {
@@ -672,6 +682,7 @@
// TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list)
bool is_dt_needed_;
// END OF WORKAROUND
+ const android_namespace_t* const start_from_;
DISALLOW_IMPLICIT_CONSTRUCTORS(LoadTask);
};
@@ -1041,7 +1052,7 @@
ZipArchiveCache* zip_archive_cache,
const char* name, soinfo *needed_by,
off64_t* file_offset, std::string* realpath) {
- TRACE("[ opening %s ]", name);
+ TRACE("[ opening %s at 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) {
@@ -1273,7 +1284,7 @@
}
for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
- load_tasks->push_back(LoadTask::create(name, si, task->get_readers_map()));
+ load_tasks->push_back(LoadTask::create(name, si, ns, task->get_readers_map()));
});
return true;
@@ -1368,8 +1379,7 @@
}
static bool find_library_in_linked_namespace(const android_namespace_link_t& namespace_link,
- LoadTask* task,
- int rtld_flags) {
+ LoadTask* task) {
android_namespace_t* ns = namespace_link.linked_namespace();
soinfo* candidate;
@@ -1394,29 +1404,10 @@
return true;
}
- // try to load the library - once namespace boundary is crossed
- // we need to load a library within separate load_group
- // to avoid using symbols from foreign namespace while.
- //
- // All symbols during relocation should be resolved within a
- // namespace to preserve library locality to a namespace.
- const char* name = task->get_name();
- if (find_libraries(ns,
- task->get_needed_by(),
- &name,
- 1,
- &candidate,
- nullptr /* ld_preloads */,
- 0 /* ld_preload_count*/,
- rtld_flags,
- nullptr /* extinfo*/,
- false /* add_as_children */,
- false /* search_linked_namespaces */)) {
- task->set_soinfo(candidate);
- return true;
- }
-
- return false;
+ // returning true with empty soinfo means that the library is okay to be
+ // loaded in the namespace buy has not yet been loaded there before.
+ task->set_soinfo(nullptr);
+ return true;
}
static bool find_library_internal(android_namespace_t* ns,
@@ -1445,9 +1436,24 @@
// if a library was not found - look into linked namespaces
for (auto& linked_namespace : ns->linked_namespaces()) {
if (find_library_in_linked_namespace(linked_namespace,
- task,
- rtld_flags)) {
- return true;
+ 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
+ // to avoid using symbols from foreign namespace while.
+ //
+ // However, actual linking is deferred until when the global group
+ // is fully identified and is applied to all namespaces.
+ // 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)) {
+ return true;
+ }
+ // lib was not found in the namespace. Try next linked namespace.
+ } else {
+ // lib is already loaded
+ return true;
+ }
}
}
}
@@ -1458,44 +1464,6 @@
static void soinfo_unload(soinfo* si);
static void soinfo_unload(soinfo* soinfos[], size_t count);
-// TODO: this is slightly unusual way to construct
-// the global group for relocation. Not every RTLD_GLOBAL
-// library is included in this group for backwards-compatibility
-// reasons.
-//
-// This group consists of the main executable, LD_PRELOADs
-// and libraries with the DF_1_GLOBAL flag set.
-static soinfo_list_t make_global_group(android_namespace_t* ns) {
- soinfo_list_t global_group;
- ns->soinfo_list().for_each([&](soinfo* si) {
- if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
- global_group.push_back(si);
- }
- });
-
- return global_group;
-}
-
-// This function provides a list of libraries to be shared
-// by the namespace. For the default namespace this is the global
-// group (see make_global_group). For all others this is a group
-// of RTLD_GLOBAL libraries (which includes the global group from
-// the default namespace).
-static soinfo_list_t get_shared_group(android_namespace_t* ns) {
- if (ns == &g_default_namespace) {
- return make_global_group(ns);
- }
-
- soinfo_list_t shared_group;
- ns->soinfo_list().for_each([&](soinfo* si) {
- if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
- shared_group.push_back(si);
- }
- });
-
- return shared_group;
-}
-
static void shuffle(std::vector<LoadTask*>* v) {
for (size_t i = 0, size = v->size(); i < size; ++i) {
size_t n = size - i;
@@ -1518,19 +1486,17 @@
int rtld_flags,
const android_dlextinfo* extinfo,
bool add_as_children,
- bool search_linked_namespaces) {
+ bool search_linked_namespaces,
+ std::unordered_map<const soinfo*, ElfReader>& readers_map,
+ std::vector<android_namespace_t*>* namespaces) {
// Step 0: prepare.
LoadTaskList load_tasks;
- std::unordered_map<const soinfo*, ElfReader> readers_map;
for (size_t i = 0; i < library_names_count; ++i) {
const char* name = library_names[i];
- load_tasks.push_back(LoadTask::create(name, start_with, &readers_map));
+ load_tasks.push_back(LoadTask::create(name, start_with, ns, &readers_map));
}
- // Construct global_group.
- soinfo_list_t global_group = make_global_group(ns);
-
// If soinfos array is null allocate one on stack.
// The array is needed in case of failure; for example
// when library_names[] = {libone.so, libtwo.so} and libone.so
@@ -1570,7 +1536,12 @@
task->set_extinfo(is_dt_needed ? nullptr : extinfo);
task->set_dt_needed(is_dt_needed);
- if (!find_library_internal(ns,
+ // try to find the load.
+ // 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
+ // current namespace but in one of the linked namespace.
+ if (!find_library_internal(const_cast<android_namespace_t*>(task->get_start_from()),
task,
&zip_archive_cache,
&load_tasks,
@@ -1629,18 +1600,61 @@
}
}
- // Step 4: Add LD_PRELOADed libraries to the global group for
- // future runs. There is no need to explicitly add them to
- // the global group for this run because they are going to
- // appear in the local group in the correct order.
+ // Step 4: Construct the global group. Note: DF_1_GLOBAL bit of a library is
+ // determined at step 3.
+
+ // Step 4-1: DF_1_GLOBAL bit is force set for LD_PRELOADed libs because they
+ // must be added to the global group
if (ld_preloads != nullptr) {
for (auto&& si : *ld_preloads) {
si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
}
}
+ // Step 4-2: Gather all DF_1_GLOBAL libs which were newly loaded during this
+ // run. These will be the new member of the global group
+ soinfo_list_t new_global_group_members;
+ for (auto&& task : load_tasks) {
+ soinfo* si = task->get_soinfo();
+ if (!si->is_linked() && (si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
+ new_global_group_members.push_back(si);
+ }
+ }
- // Step 5: link libraries.
+ // Step 4-3: Add the new global group members to all the linked namespaces
+ for (auto si : new_global_group_members) {
+ for (auto linked_ns : *namespaces) {
+ if (si->get_primary_namespace() != linked_ns) {
+ linked_ns->add_soinfo(si);
+ si->add_secondary_namespace(linked_ns);
+ }
+ }
+ }
+
+ // Step 5: link libraries that are not destined to this namespace.
+ // Do this by recursively calling find_libraries on the namespace where the lib
+ // was found during Step 1.
+ for (auto&& task : load_tasks) {
+ soinfo* si = task->get_soinfo();
+ if (si->get_primary_namespace() != ns) {
+ const char* name = task->get_name();
+ if (find_libraries(si->get_primary_namespace(), task->get_needed_by(), &name, 1,
+ nullptr /* soinfos */, nullptr /* ld_preloads */, 0 /* ld_preload_count */,
+ rtld_flags, nullptr /* extinfo */, false /* add_as_children */,
+ false /* search_linked_namespaces */, readers_map, namespaces)) {
+ // If this lib is directly needed by one of the libs in this namespace,
+ // then increment the count
+ soinfo* needed_by = task->get_needed_by();
+ if (needed_by != nullptr && needed_by->get_primary_namespace() == ns && si->is_linked()) {
+ si->increment_ref_count();
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+
+ // Step 6: link libraries in this namespace
soinfo_list_t local_group;
walk_dependencies_tree(
(start_with != nullptr && add_as_children) ? &start_with : soinfos,
@@ -1654,6 +1668,7 @@
}
});
+ soinfo_list_t global_group = ns->get_global_group();
bool linked = local_group.visit([&](soinfo* si) {
if (!si->is_linked()) {
if (!si->link_image(global_group, local_group, extinfo) ||
@@ -1684,6 +1699,9 @@
soinfo* needed_by) {
soinfo* si;
+ // readers_map is shared across recursive calls to find_libraries.
+ // However, the map is not shared across different threads.
+ std::unordered_map<const soinfo*, ElfReader> readers_map;
if (name == nullptr) {
si = solist_get_somain();
} else if (!find_libraries(ns,
@@ -1696,7 +1714,8 @@
rtld_flags,
extinfo,
false /* add_as_children */,
- true /* search_linked_namespaces */)) {
+ true /* search_linked_namespaces */,
+ readers_map)) {
return nullptr;
}
@@ -2208,7 +2227,7 @@
}
} else {
// If not shared - copy only the shared group
- add_soinfos_to_namespace(get_shared_group(parent_namespace), ns);
+ add_soinfos_to_namespace(parent_namespace->get_shared_group(), ns);
}
ns->set_ld_library_paths(std::move(ld_library_paths));
@@ -3413,7 +3432,7 @@
return true;
}
-static void init_default_namespace_no_config(bool is_asan) {
+static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan) {
g_default_namespace.set_isolated(false);
auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : kDefaultLdPaths;
@@ -3428,9 +3447,13 @@
}
g_default_namespace.set_default_library_paths(std::move(ld_default_paths));
+
+ std::vector<android_namespace_t*> namespaces;
+ namespaces.push_back(&g_default_namespace);
+ return namespaces;
}
-void init_default_namespace(const char* executable_path) {
+std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path) {
g_default_namespace.set_name("(default)");
soinfo* somain = solist_get_somain();
@@ -3447,14 +3470,24 @@
std::string error_msg;
- if (!Config::read_binary_config(kLdConfigFilePath,
+ const char* config_file = file_exists(kLdConfigArchFilePath) ? kLdConfigArchFilePath : kLdConfigFilePath;
+#ifdef USE_LD_CONFIG_FILE
+ // This is a debugging/testing only feature. Must not be available on
+ // production builds.
+ const char* ld_config_file = getenv("LD_CONFIG_FILE");
+ if (ld_config_file != nullptr && file_exists(ld_config_file)) {
+ config_file = ld_config_file;
+ }
+#endif
+
+ if (!Config::read_binary_config(config_file,
executable_path,
g_is_asan,
&config,
&error_msg)) {
if (!error_msg.empty()) {
DL_WARN("error reading config file \"%s\" for \"%s\" (will use default configuration): %s",
- kLdConfigFilePath,
+ config_file,
executable_path,
error_msg.c_str());
}
@@ -3462,8 +3495,7 @@
}
if (config == nullptr) {
- init_default_namespace_no_config(g_is_asan);
- return;
+ return init_default_namespace_no_config(g_is_asan);
}
const auto& namespace_configs = config->namespace_configs();
@@ -3477,6 +3509,9 @@
g_default_namespace.set_permitted_paths(default_ns_config->permitted_paths());
namespaces[default_ns_config->name()] = &g_default_namespace;
+ if (default_ns_config->visible()) {
+ g_exported_namespaces[default_ns_config->name()] = &g_default_namespace;
+ }
// 2. Initialize other namespaces
@@ -3514,10 +3549,17 @@
soinfo* ld_android_so = solist_get_head();
for (auto it : namespaces) {
it.second->add_soinfo(ld_android_so);
- // TODO (dimitry): somain and ld_preloads should probably be added to all of these namespaces too?
+ // somain and ld_preloads are added to these namespaces after LD_PRELOAD libs are linked
}
set_application_target_sdk_version(config->target_sdk_version());
+
+ std::vector<android_namespace_t*> created_namespaces;
+ created_namespaces.reserve(namespaces.size());
+ for (auto kv : namespaces) {
+ created_namespaces.push_back(kv.second);
+ }
+ return created_namespaces;
}
// This function finds a namespace exported in ld.config.txt by its name.
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 0a9aeab..2bdde1e 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -371,6 +371,15 @@
bool is_asan,
const Config** config,
std::string* error_msg) {
+ // TODO(b/38114603) Currently, multiple namespaces does not support ASAN mode
+ // where some symbols should be intercepted via LD_PRELOAD; LD_PRELOADed libs
+ // are not being preloaded into the linked namespaces other than the default
+ // namespace. Until we fix the problem, we temporarily disable ld.config.txt
+ // in ASAN mode.
+ if (is_asan) {
+ return false;
+ }
+
g_config.clear();
std::unordered_map<std::string, PropertyValue> property_map;
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 3f7795b..54593e4 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -203,6 +203,10 @@
static char kLinkerPath[] = "/system/bin/linker";
#endif
+static void __linker_cannot_link(const char* argv0) {
+ async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer());
+}
+
/*
* This code is called after the linker has linked itself and
* fixed it's own GOT. It is safe to make references to externs
@@ -317,17 +321,17 @@
// We haven't supported non-PIE since Lollipop for security reasons.
if (elf_hdr->e_type != ET_DYN) {
- // We don't use __libc_fatal here because we don't want a tombstone: it's
- // been several years now but we still find ourselves on app compatibility
+ // We don't use async_safe_fatal here because we don't want a tombstone:
+ // even after several years we still find ourselves on app compatibility
// investigations because some app's trying to launch an executable that
// hasn't worked in at least three years, and we've "helpfully" dropped a
// tombstone for them. The tombstone never provided any detail relevant to
// fixing the problem anyway, and the utility of drawing extra attention
// to the problem is non-existent at this late date.
async_safe_format_fd(STDERR_FILENO,
- "\"%s\": error: Android 5.0 and later only support "
- "position-independent executables (-fPIE).\n",
- g_argv[0]);
+ "\"%s\": error: Android 5.0 and later only support "
+ "position-independent executables (-fPIE).\n",
+ g_argv[0]);
exit(EXIT_FAILURE);
}
@@ -337,14 +341,19 @@
somain = si;
- init_default_namespace(executable_path);
+ std::vector<android_namespace_t*> namespaces = init_default_namespaces(executable_path);
- if (!si->prelink_image()) {
- async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
- }
+ if (!si->prelink_image()) __linker_cannot_link(g_argv[0]);
// add somain to global group
si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
+ // ... and add it to all other linked namespaces
+ for (auto linked_ns : namespaces) {
+ if (linked_ns != &g_default_namespace) {
+ linked_ns->add_soinfo(somain);
+ somain->add_secondary_namespace(linked_ns);
+ }
+ }
// Load ld_preloads and dependencies.
std::vector<const char*> needed_library_name_list;
@@ -362,6 +371,9 @@
const char** needed_library_names = &needed_library_name_list[0];
size_t needed_libraries_count = needed_library_name_list.size();
+ // readers_map is shared across recursive calls to find_libraries so that we
+ // don't need to re-load elf headers.
+ std::unordered_map<const soinfo*, ElfReader> readers_map;
if (needed_libraries_count > 0 &&
!find_libraries(&g_default_namespace,
si,
@@ -373,20 +385,20 @@
RTLD_GLOBAL,
nullptr,
true /* add_as_children */,
- true /* search_linked_namespaces */)) {
- async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
+ true /* search_linked_namespaces */,
+ readers_map,
+ &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)) {
- async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
+ __linker_cannot_link(g_argv[0]);
}
si->increment_ref_count();
}
add_vdso(args);
- if (!get_cfi_shadow()->InitialLinkDone(solist)) {
- async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
- }
+ if (!get_cfi_shadow()->InitialLinkDone(solist)) __linker_cannot_link(g_argv[0]);
si->call_pre_init_constructors();
@@ -468,10 +480,6 @@
return 0;
}
-static void __linker_cannot_link(const char* argv0) {
- async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer());
-}
-
/*
* This is the entry point for the linker, called from begin.S. This
* method is responsible for fixing the linker's own relocations, and
diff --git a/linker/linker_main.h b/linker/linker_main.h
index 8f3f07c..2cf30c2 100644
--- a/linker/linker_main.h
+++ b/linker/linker_main.h
@@ -31,6 +31,9 @@
#include <android/dlext.h>
+#include <unordered_map>
+#include <vector>
+
#include "linker_namespaces.h"
#include "linker_soinfo.h"
@@ -44,7 +47,9 @@
static size_t ref_count_;
};
-void init_default_namespace(const char* executable_path);
+class ElfReader;
+
+std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path);
soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
struct stat* file_stat, off64_t file_offset,
uint32_t rtld_flags);
@@ -59,7 +64,9 @@
int rtld_flags,
const android_dlextinfo* extinfo,
bool add_as_children,
- bool search_linked_namespaces);
+ bool search_linked_namespaces,
+ std::unordered_map<const soinfo*, ElfReader>& readers_map,
+ std::vector<android_namespace_t*>* namespaces = nullptr);
void solist_add_soinfo(soinfo* si);
bool solist_remove_soinfo(soinfo* si);
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
index 3c86f99..9fdf0b5 100644
--- a/linker/linker_namespaces.cpp
+++ b/linker/linker_namespaces.cpp
@@ -31,6 +31,8 @@
#include "linker_soinfo.h"
#include "linker_utils.h"
+#include <dlfcn.h>
+
bool android_namespace_t::is_accessible(const std::string& file) {
if (!is_isolated_) {
return true;
@@ -86,3 +88,41 @@
return !is_accessible_ftor(si);
});
}
+
+// TODO: this is slightly unusual way to construct
+// the global group for relocation. Not every RTLD_GLOBAL
+// library is included in this group for backwards-compatibility
+// reasons.
+//
+// This group consists of the main executable, LD_PRELOADs
+// and libraries with the DF_1_GLOBAL flag set.
+soinfo_list_t android_namespace_t::get_global_group() {
+ soinfo_list_t global_group;
+ soinfo_list().for_each([&](soinfo* si) {
+ if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
+ global_group.push_back(si);
+ }
+ });
+
+ return global_group;
+}
+
+// This function provides a list of libraries to be shared
+// by the namespace. For the default namespace this is the global
+// group (see get_global_group). For all others this is a group
+// of RTLD_GLOBAL libraries (which includes the global group from
+// the default namespace).
+soinfo_list_t android_namespace_t::get_shared_group() {
+ if (this == &g_default_namespace) {
+ return get_global_group();
+ }
+
+ soinfo_list_t shared_group;
+ soinfo_list().for_each([&](soinfo* si) {
+ if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
+ shared_group.push_back(si);
+ }
+ });
+
+ return shared_group;
+}
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index 1099b6b..16906d6 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -136,6 +136,9 @@
// or one of it's parent soinfos belongs to this namespace.
bool is_accessible(soinfo* si);
+ soinfo_list_t get_global_group();
+ soinfo_list_t get_shared_group();
+
private:
const char* name_;
bool is_isolated_;
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 42c29c8..a9873c4 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -147,8 +147,9 @@
}
bool ElfReader::Read(const char* name, int fd, off64_t file_offset, off64_t file_size) {
- CHECK(!did_read_);
- CHECK(!did_load_);
+ if (did_read_) {
+ return true;
+ }
name_ = name;
fd_ = fd;
file_offset_ = file_offset;
@@ -167,7 +168,9 @@
bool ElfReader::Load(const android_dlextinfo* extinfo) {
CHECK(did_read_);
- CHECK(!did_load_);
+ if (did_load_) {
+ return true;
+ }
if (ReserveAddressSpace(extinfo) &&
LoadSegments() &&
FindPhdr()) {
diff --git a/linker/tests/linker_config_test.cpp b/linker/tests/linker_config_test.cpp
index c6fade9..87609d0 100644
--- a/linker/tests/linker_config_test.cpp
+++ b/linker/tests/linker_config_test.cpp
@@ -168,6 +168,7 @@
run_linker_config_smoke_test(false);
}
-TEST(linker_config, asan_smoke) {
- run_linker_config_smoke_test(true);
-}
+// TODO(b/38114603) revive this test when ld.config.txt is enabled for ASAN mode
+//TEST(linker_config, asan_smoke) {
+// run_linker_config_smoke_test(true);
+//}
diff --git a/tests/Android.bp b/tests/Android.bp
index d4027b3..b5f8dc8 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -70,6 +70,7 @@
"getauxval_test.cpp",
"getcwd_test.cpp",
"grp_pwd_test.cpp",
+ "iconv_test.cpp",
"ifaddrs_test.cpp",
"inttypes_test.cpp",
"langinfo_test.cpp",
@@ -192,6 +193,26 @@
},
}
+// If building this fails, then we have both FORTIFY and ASAN enabled, which
+// isn't desirable. (Ideally, we'd emit FORTIFY diagnostics even with ASAN
+// enabled, but that's not a reality today.) This is meant to be otherwise
+// unused.
+cc_test_library {
+ name: "fortify_disabled_for_asan",
+ cflags: [
+ "-Werror",
+ "-D_FORTIFY_SOURCE=2",
+ // "sanitize: address" doesn't work on platforms where libasan isn't
+ // enabled. Since the intent is just to build this, we can get away with
+ // passing this flag on its own.
+ "-fsanitize=address",
+ ],
+ // Ignore that we don't have ASAN symbols linked in.
+ allow_undefined_symbols: true,
+ srcs: ["fortify_compilation_test.cpp"],
+ clang: true,
+}
+
cc_test_library {
name: "libfortify1-tests-clang",
defaults: ["bionic_fortify_tests_defaults", "bionic_tests_defaults"],
@@ -298,7 +319,13 @@
"libLLVMSupport",
],
}
- }
+ },
+
+ product_variables: {
+ debuggable: {
+ cppflags: ["-DUSE_LD_CONFIG_FILE"],
+ },
+ },
}
// -----------------------------------------------------------------------------
@@ -527,7 +554,6 @@
static_libs: [
"libm",
"libc",
- "libc++_static",
"libdl",
"libtinyxml2",
"liblog",
@@ -537,12 +563,6 @@
static_executable: true,
stl: "libc++_static",
-
- // libc and libc++ both define std::nothrow. libc's is a private symbol, but this
- // still causes issues when linking libc.a and libc++.a, since private isn't
- // effective until it has been linked. To fix this, just allow multiple symbol
- // definitions for the static tests.
- ldflags: ["-Wl,--allow-multiple-definition"],
}
// -----------------------------------------------------------------------------
@@ -599,6 +619,12 @@
sanitize: {
never: false,
},
+
+ product_variables: {
+ debuggable: {
+ cppflags: ["-DUSE_LD_CONFIG_FILE"],
+ },
+ },
}
subdirs = ["libs"]
diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp
index 3d6fcaa..e71ba7a 100644
--- a/tests/async_safe_test.cpp
+++ b/tests/async_safe_test.cpp
@@ -181,8 +181,20 @@
char buf[BUFSIZ];
ASSERT_EQ(11, async_safe_format_buffer(buf, sizeof(buf), "hello %s", "world"));
EXPECT_STREQ("hello world", buf);
+
ASSERT_EQ(11, async_safe_format_buffer(buf, 8, "hello %s", "world"));
EXPECT_STREQ("hello w", buf);
+
+ ASSERT_EQ(11, async_safe_format_buffer(buf, 6, "hello %s", "world"));
+ EXPECT_STREQ("hello", buf);
+
+ ASSERT_EQ(4, async_safe_format_buffer(nullptr, 0, "xxxx"));
+
+ ASSERT_EQ(4, async_safe_format_buffer(buf, 1, "xxxx"));
+ EXPECT_STREQ("", buf);
+
+ ASSERT_EQ(4, async_safe_format_buffer(buf, 2, "xxxx"));
+ EXPECT_STREQ("x", buf);
#else // __BIONIC__
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif // __BIONIC__
diff --git a/tests/cfi_test.cpp b/tests/cfi_test.cpp
index 5e627a7..088dda6 100644
--- a/tests/cfi_test.cpp
+++ b/tests/cfi_test.cpp
@@ -26,6 +26,7 @@
extern "C" {
void __cfi_slowpath(uint64_t CallSiteTypeId, void* Ptr);
void __cfi_slowpath_diag(uint64_t CallSiteTypeId, void* Ptr, void* DiagData);
+size_t __cfi_shadow_size();
}
static void f() {}
@@ -36,6 +37,8 @@
handle = dlopen("libcfi-test.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
+ EXPECT_NE(0U, __cfi_shadow_size());
+
#define SYM(type, name) auto name = reinterpret_cast<type>(dlsym(handle, #name))
SYM(int (*)(), get_count);
SYM(uint64_t(*)(), get_last_type_id);
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index f18fac5..3a5ef74 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -28,7 +28,7 @@
// libc++ actively gets in the way of including <complex.h> from C++, so we
// have to be naughty.
-#include <../libc/include/complex.h>
+#include "../libc/include/complex.h"
// (libc++ also seems to have really bad implementations of its own that ignore
// the intricacies of floating point math.)
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index aa8bd57..857640a 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -23,6 +23,8 @@
#include <stdint.h>
#include <string>
+#include <iostream>
+#include <fstream>
#include "gtest_globals.h"
#include "utils.h"
@@ -109,4 +111,131 @@
#endif
}
-// TODO: Add tests for LD_PRELOADs
+
+TEST(dl, exec_without_ld_preload) {
+#if defined(__BIONIC__)
+ std::string helper = get_testlib_root() +
+ "/ld_preload_test_helper/ld_preload_test_helper";
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345");
+#endif
+}
+
+TEST(dl, exec_with_ld_preload) {
+#if defined(__BIONIC__)
+ std::string helper = get_testlib_root() +
+ "/ld_preload_test_helper/ld_preload_test_helper";
+ std::string env = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_preload_test_helper_lib2.so";
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.SetEnv({ env.c_str(), nullptr });
+ // ld_preload_test_helper calls get_value_from_lib() and returns the value.
+ // The symbol is defined by two libs: ld_preload_test_helper_lib.so and
+ // ld_preloaded_lib.so. The former is DT_NEEDED and the latter is LD_PRELOADED
+ // via this execution. The main executable is linked to the LD_PRELOADED lib
+ // and the value given from the lib is returned.
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321");
+#endif
+}
+
+
+// ld_config_test_helper must fail because it is depending on a lib which is not
+// in the search path
+//
+// Call sequence is...
+// _helper -- (get_value_from_lib()) -->
+// _lib1.so -- (get_value_from_another_lib()) -->
+// _lib2.so (returns 12345)
+// The two libs are in ns2/ subdir.
+TEST(dl, exec_without_ld_config_file) {
+#if defined(__BIONIC__)
+ std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n";
+ std::string helper = get_testlib_root() +
+ "/ld_config_test_helper/ld_config_test_helper";
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());
+#endif
+}
+
+#if defined(__BIONIC__)
+static void create_ld_config_file(std::string& config_file) {
+ std::ofstream fout(config_file.c_str(), std::ios::out);
+ fout << "dir.test = " << get_testlib_root() << "/ld_config_test_helper/" << std::endl
+ << "[test]" << std::endl
+ << "additional.namespaces = ns2" << std::endl
+ << "namespace.default.search.paths = " << get_testlib_root() << std::endl
+ << "namespace.default.links = ns2" << std::endl
+ << "namespace.default.link.ns2.shared_libs = libc.so:libm.so:libdl.so:ld_config_test_helper_lib1.so" << std::endl
+ << "namespace.ns2.search.paths = /system/${LIB}:" << get_testlib_root() << "/ns2" << std::endl;
+ fout.close();
+}
+#endif
+
+#ifdef USE_LD_CONFIG_FILE
+
+// _lib1.so and _lib2.so are now searchable by having another namespace 'ns2'
+// whose search paths include the 'ns2/' subdir.
+TEST(dl, exec_with_ld_config_file) {
+#if defined(__BIONIC__)
+ std::string helper = get_testlib_root() +
+ "/ld_config_test_helper/ld_config_test_helper";
+ std::string config_file = get_testlib_root() + "/ld.config.txt";
+ create_ld_config_file(config_file);
+ std::string env = std::string("LD_CONFIG_FILE=") + config_file;
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.SetEnv({ env.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345");
+#endif
+}
+
+// _lib3.so has same symbol as lib2.so but returns 54321. _lib3.so is
+// LD_PRELOADed. This test is to ensure LD_PRELOADed libs are available to
+// additional namespaces other than the default namespace.
+TEST(dl, exec_with_ld_config_file_with_ld_preload) {
+#if defined(__BIONIC__)
+ std::string helper = get_testlib_root() +
+ "/ld_config_test_helper/ld_config_test_helper";
+ std::string config_file = get_testlib_root() + "/ld.config.txt";
+ create_ld_config_file(config_file);
+ std::string env = std::string("LD_CONFIG_FILE=") + config_file;
+ std::string env2 = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_config_test_helper_lib3.so";
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.SetEnv({ env.c_str(), env2.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321");
+#endif
+}
+
+#endif // USE_LD_CONFIG_FILE
+
+// ensures that LD_CONFIG_FILE env var does not work for production builds.
+// The test input is the same as exec_with_ld_config_file, but it must fail in
+// this case.
+TEST(dl, disable_ld_config_file) {
+#if defined(__BIONIC__)
+ if (getuid() == 0) {
+ // when executed from the shell (e.g. not as part of CTS), skip the test.
+ // This test is only for CTS.
+ return;
+ }
+ std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n";
+ std::string helper = get_testlib_root() +
+ "/ld_config_test_helper/ld_config_test_helper";
+ std::string config_file = get_testlib_root() + "/ld.config.txt";
+ create_ld_config_file(config_file);
+ std::string env = std::string("LD_CONFIG_FILE=") + config_file;
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.SetEnv({ env.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());
+#endif
+}
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index b264e53..0dc54d0 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -824,7 +824,7 @@
const std::string lib_path = get_testlib_root() + "/libtest_simple.so";
int tmpfd = TEMP_FAILURE_RETRY(
- open(get_testlib_root().c_str(), O_TMPFILE | O_CLOEXEC | O_RDWR | O_EXCL));
+ open(get_testlib_root().c_str(), O_TMPFILE | O_CLOEXEC | O_RDWR | O_EXCL, 0));
// Ignore kernels without O_TMPFILE flag support
if (tmpfd == -1 && (errno == EISDIR || errno == EINVAL || errno == EOPNOTSUPP)) {
diff --git a/tests/fcntl_test.cpp b/tests/fcntl_test.cpp
index 1bef0f4..7e78830 100644
--- a/tests/fcntl_test.cpp
+++ b/tests/fcntl_test.cpp
@@ -20,12 +20,16 @@
#include <fcntl.h>
#include <string.h>
#include <sys/utsname.h>
+#include <sys/vfs.h>
#include "TemporaryFile.h"
+#include <android-base/stringprintf.h>
+
// Glibc v2.19 doesn't include these in fcntl.h so host builds will fail without.
#if !defined(FALLOC_FL_PUNCH_HOLE) || !defined(FALLOC_FL_KEEP_SIZE)
#include <linux/falloc.h>
+#include <linux/magic.h>
#endif
TEST(fcntl, fcntl_smoke) {
@@ -288,7 +292,51 @@
if (major < 4 || (major == 4 && minor < 1)) {
TemporaryFile tf;
- ASSERT_EQ(-1, fallocate(tf.fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 1));
- ASSERT_EQ(errno, EOPNOTSUPP);
+ struct statfs sfs;
+ ASSERT_EQ(0, fstatfs(tf.fd, &sfs));
+ if (sfs.f_type == EXT4_SUPER_MAGIC) {
+ ASSERT_EQ(-1, fallocate(tf.fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 1));
+ ASSERT_EQ(errno, EOPNOTSUPP);
+ }
}
}
+
+TEST(fcntl, open_O_TMPFILE_mode) {
+#if __BIONIC__ // Our glibc is too old for O_TMPFILE.
+ TemporaryDir dir;
+ // Without O_EXCL, we're allowed to give this a name later.
+ // (This is unrelated to the O_CREAT interaction with O_EXCL.)
+ const mode_t perms = S_IRUSR | S_IWUSR;
+ int fd = open(dir.dirname, O_TMPFILE | O_RDWR, perms);
+
+ // Ignore kernels without O_TMPFILE support (< 3.11).
+ if (fd == -1 && (errno == EISDIR || errno == EINVAL || errno == EOPNOTSUPP)) return;
+
+ ASSERT_TRUE(fd != -1) << strerror(errno);
+
+ // Does the fd claim to have the mode we set?
+ struct stat sb = {};
+ ASSERT_EQ(0, fstat(fd, &sb));
+ ASSERT_EQ(perms, (sb.st_mode & ~S_IFMT));
+
+ std::string final_path = android::base::StringPrintf("%s/named_now", dir.dirname);
+ ASSERT_EQ(0, linkat(AT_FDCWD, android::base::StringPrintf("/proc/self/fd/%d", fd).c_str(),
+ AT_FDCWD, final_path.c_str(),
+ AT_SYMLINK_FOLLOW));
+ ASSERT_EQ(0, close(fd));
+
+ // Does the resulting file claim to have the mode we set?
+ ASSERT_EQ(0, stat(final_path.c_str(), &sb));
+ ASSERT_EQ(perms, (sb.st_mode & ~S_IFMT));
+
+ // With O_EXCL, you're not allowed to add a name later.
+ fd = open(dir.dirname, O_TMPFILE | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
+ ASSERT_TRUE(fd != -1) << strerror(errno);
+ errno = 0;
+ ASSERT_EQ(-1, linkat(AT_FDCWD, android::base::StringPrintf("/proc/self/fd/%d", fd).c_str(),
+ AT_FDCWD, android::base::StringPrintf("%s/no_chance", dir.dirname).c_str(),
+ AT_SYMLINK_FOLLOW));
+ ASSERT_EQ(ENOENT, errno);
+ ASSERT_EQ(0, close(fd));
+#endif
+}
diff --git a/tests/fortify_compilation_test.cpp b/tests/fortify_compilation_test.cpp
index 51074b2..c6198c6 100644
--- a/tests/fortify_compilation_test.cpp
+++ b/tests/fortify_compilation_test.cpp
@@ -14,6 +14,22 @@
* limitations under the License.
*/
+/*
+ * If this test fails, you can see the compiler's output by erasing a few args from the failing
+ * command. Specifically, delete everything before the path/to/the/compiler, then delete the first
+ * arg after the path/to/the/compiler. For example, given the following command:
+ *
+ * bionic/tests/file-check-cxx out/host/linux-x86/bin/FileCheck \
+ * prebuilts/clang/host/linux-x86/clang-4053586/bin/clang++ CLANG -I bionic/tests -I ...
+ *
+ * If you delete everything before clang++ and delete "CLANG" (or "GCC" if gcc is failing), then
+ * you'll end up with:
+ *
+ * prebuilts/clang/host/linux-x86/clang-4053586/bin/clang++ -I bionic/tests -I ...
+ *
+ * Which is the command that FileCheck executes.
+ */
+
#undef _FORTIFY_SOURCE
#define _FORTIFY_SOURCE 2
#include <fcntl.h>
@@ -71,7 +87,7 @@
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: warning: call to void* __builtin___memcpy_chk(void*, const void*, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
- // CLANG: error: call to unavailable function 'memcpy': memcpy called with size bigger than buffer
+ // CLANG: error: 'memcpy' called with size bigger than buffer
memcpy(buf, "foobar", sizeof("foobar") + 100);
}
@@ -80,7 +96,7 @@
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: warning: call to void* __builtin___memmove_chk(void*, const void*, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
- // CLANG: error: call to unavailable function 'memmove': memmove called with size bigger than buffer
+ // CLANG: error: 'memmove' called with size bigger than buffer
memmove(buf, "foobar", sizeof("foobar"));
}
@@ -89,7 +105,7 @@
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: warning: call to void* __builtin___memset_chk(void*, int, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
- // CLANG: error: call to unavailable function 'memset': memset called with size bigger than buffer
+ // CLANG: error: 'memset' called with size bigger than buffer
memset(buf, 0, 6);
}
@@ -98,8 +114,13 @@
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: warning: call to {{(char\* __builtin___strcpy_chk\(char\*, const char\*, unsigned int\))|(void\* __builtin___memcpy_chk\(void\*, const void\*, (long )?unsigned int, (long )?unsigned int\))}} will always overflow destination buffer
- // CLANG: error: call to unavailable function 'strcpy': strcpy called with string bigger than buffer
+ // CLANG: error: 'strcpy' called with string bigger than buffer
strcpy(buf, "foobar"); // NOLINT(runtime/printf)
+
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // GCC: warning: call to {{(char\* __builtin___strcpy_chk\(char\*, const char\*, unsigned int\))|(void\* __builtin___memcpy_chk\(void\*, const void\*, (long )?unsigned int, (long )?unsigned int\))}} will always overflow destination buffer
+ // CLANG: error: 'strcpy' called with string bigger than buffer
+ strcpy(buf, "quux");
}
void test_stpcpy() {
@@ -107,8 +128,13 @@
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: warning: call to char* __builtin___stpcpy_chk(char*, const char*, {{(long )?}}unsigned int) will always overflow destination buffer
- // CLANG: error: call to unavailable function 'stpcpy': stpcpy called with string bigger than buffer
+ // CLANG: error: 'stpcpy' called with string bigger than buffer
stpcpy(buf, "foobar");
+
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // GCC: warning: call to char* __builtin___stpcpy_chk(char*, const char*, {{(long )?}}unsigned int) will always overflow destination buffer
+ // CLANG: error: 'stpcpy' called with string bigger than buffer
+ stpcpy(buf, "quux");
}
void test_strncpy() {
@@ -169,12 +195,12 @@
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fgets_too_small_error' declared with attribute error: fgets called with size less than zero
- // CLANG: error: call to unavailable function 'fgets': size is negative
+ // CLANG: error: in call to 'fgets', size should not be negative
fgets(buf, -1, stdin);
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fgets_too_big_error' declared with attribute error: fgets called with size bigger than buffer
- // CLANG: error: call to unavailable function 'fgets': size is larger than the destination buffer
+ // CLANG: error: in call to 'fgets', size is larger than the destination buffer
fgets(buf, 6, stdin);
}
@@ -183,15 +209,24 @@
sockaddr_in addr;
// NOLINTNEXTLINE(whitespace/line_length)
- // GCC: error: call to '__recvfrom_error' declared with attribute error: recvfrom called with size bigger than buffer
- // CLANG: error: call to unavailable function 'recvfrom': recvfrom called with size bigger than buffer
+ // GCC: error: call to '__recvfrom_error' declared with attribute error: 'recvfrom' called with size bigger than buffer
+ // CLANG: error: 'recvfrom' called with size bigger than buffer
recvfrom(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), NULL);
}
+void test_recv() {
+ char buf[4] = {0};
+
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // GCC: error: call to '__recvfrom_error' declared with attribute error: 'recvfrom' called with size bigger than buffer
+ // CLANG: error: 'recv' called with size bigger than buffer
+ recv(0, buf, 6, 0);
+}
+
void test_umask() {
// NOLINTNEXTLINE(whitespace/line_length)
- // GCC: error: call to '__umask_invalid_mode' declared with attribute error: umask called with invalid mode
- // CLANG: error: call to unavailable function 'umask': umask called with invalid mode
+ // GCC: error: call to '__umask_invalid_mode' declared with attribute error: 'umask' called with invalid mode
+ // CLANG: error: 'umask' called with invalid mode
umask(01777);
}
@@ -199,27 +234,41 @@
char buf[4];
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__read_dest_size_error' declared with attribute error: read called with size bigger than destination
- // CLANG: error: call to unavailable function 'read': 'count' bytes overflows the given object
+ // CLANG: error: in call to 'read', 'count' bytes overflows the given object
read(0, buf, 6);
}
void test_open() {
// NOLINTNEXTLINE(whitespace/line_length)
- // GCC: error: call to '__creat_missing_mode' declared with attribute error: called with O_CREAT, but missing mode
- // CLANG: error: call to unavailable function 'open': called with O_CREAT, but missing mode
+ // GCC: error: call to '__creat_missing_mode' declared with attribute error: called with O_CREAT or O_TMPFILE, but missing mode
+ // CLANG: error: 'open' called with O_CREAT or O_TMPFILE, but missing mode
open("/dev/null", O_CREAT);
+ // GCC: error: call to '__creat_missing_mode' declared with attribute error: called with O_CREAT or O_TMPFILE, but missing mode
+ // CLANG: error: 'open' called with O_CREAT or O_TMPFILE, but missing mode
+ open("/dev/null", O_TMPFILE);
+
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__creat_too_many_args' declared with attribute error: too many arguments
// CLANG: error: call to unavailable function 'open': too many arguments
open("/dev/null", O_CREAT, 0, 0);
+
+ // GCC: error: call to '__creat_too_many_args' declared with attribute error: too many arguments
+ // CLANG: error: call to unavailable function 'open': too many arguments
+ open("/dev/null", O_TMPFILE, 0, 0);
+
+ // CLANG: warning: 'open' has superfluous mode bits; missing O_CREAT?
+ open("/dev/null", O_RDONLY, 0644);
+
+ // CLANG: warning: 'open' has superfluous mode bits; missing O_CREAT?
+ open("/dev/null", O_DIRECTORY, 0644);
}
void test_poll() {
pollfd fds[1];
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__poll_too_small_error' declared with attribute error: poll: pollfd array smaller than fd count
- // CLANG: error: call to unavailable function 'poll': too many fds specified
+ // CLANG: error: in call to 'poll', fd_count is larger than the given buffer
poll(fds, 2, 0);
}
@@ -228,7 +277,7 @@
timespec timeout;
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__ppoll_too_small_error' declared with attribute error: ppoll: pollfd array smaller than fd count
- // CLANG: error: call to unavailable function 'ppoll': too many fds specified
+ // CLANG: error: in call to 'ppoll', fd_count is larger than the given buffer
ppoll(fds, 2, &timeout, NULL);
}
@@ -236,7 +285,7 @@
char buf[4];
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fread_overflow' declared with attribute error: fread called with overflowing size * count
- // CLANG: error: call to unavailable function 'fread': size * count overflows
+ // CLANG: error: in call to 'fread', size * count overflows
fread(buf, 2, (size_t)-1, stdin);
}
@@ -244,7 +293,8 @@
char buf[4];
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fread_too_big_error' declared with attribute error: fread called with size * count bigger than buffer
- // CLANG: error: call to unavailable function 'fread': size * count is too large
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // CLANG: error: in call to 'fread', size * count is too large for the given buffer
fread(buf, 1, 5, stdin);
}
@@ -252,7 +302,7 @@
char buf[4] = {0};
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fwrite_overflow' declared with attribute error: fwrite called with overflowing size * count
- // CLANG: error: call to unavailable function 'fwrite': size * count overflows
+ // CLANG: error: in call to 'fwrite', size * count overflows
fwrite(buf, 2, (size_t)-1, stdout);
}
@@ -260,7 +310,8 @@
char buf[4] = {0};
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fwrite_too_big_error' declared with attribute error: fwrite called with size * count bigger than buffer
- // CLANG: error: call to unavailable function 'fwrite': size * count is too large
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // CLANG: error: in call to 'fwrite', size * count is too large for the given buffer
fwrite(buf, 1, 5, stdout);
}
@@ -268,7 +319,7 @@
char buf[4];
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__getcwd_dest_size_error' declared with attribute error: getcwd called with size bigger than destination
- // CLANG: error: call to unavailable function 'getcwd': 'size' bytes overflows the given object
+ // CLANG: error: in call to 'getcwd', 'size' bytes overflows the given object
getcwd(buf, 5);
}
@@ -276,7 +327,7 @@
char buf[4] = {0};
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__pwrite64_dest_size_error' declared with attribute error: pwrite64 called with size bigger than destination
- // CLANG: error: call to unavailable function 'pwrite64': 'count' bytes overflows the given object
+ // CLANG: error: in call to 'pwrite64', 'count' bytes overflows the given object
pwrite64(STDOUT_FILENO, buf, 5, 0);
}
@@ -292,7 +343,7 @@
char buf[4] = {0};
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__pwrite64_count_toobig_error' declared with attribute error: pwrite64 called with count > SSIZE_MAX
- // CLANG: error: call to unavailable function 'pwrite64': count must be <= SSIZE_MAX
+ // CLANG: error: in call to 'pwrite64', 'count' must be <= SSIZE_MAX
pwrite64(STDOUT_FILENO, buf, SIZE_MAX, 0);
}
@@ -300,14 +351,14 @@
char buf[4] = {0};
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__write_dest_size_error' declared with attribute error: write called with size bigger than destination
- // CLANG: error: call to unavailable function 'write': 'count' bytes overflows the given object
+ // CLANG: error: in call to 'write', 'count' bytes overflows the given object
write(STDOUT_FILENO, buf, 5);
}
void test_memset_args_flipped() {
char from[4] = {0};
// NOLINTNEXTLINE(whitespace/line_length)
- // CLANG: 'memset' is deprecated: will set 0 bytes; maybe the arguments got flipped? (Add __bionic_zero_size_is_okay as a fourth argument to silence this.)
+ // CLANG: 'memset' will set 0 bytes; maybe the arguments got flipped?
memset(from, sizeof(from), 0);
}
@@ -316,8 +367,8 @@
sockaddr_in addr;
// NOLINTNEXTLINE(whitespace/line_length)
- // GCC: error: call to '__sendto_error' declared with attribute error: sendto called with size bigger than buffer
- // CLANG: error: call to unavailable function 'sendto': sendto called with size bigger than buffer
+ // GCC: error: call to '__sendto_error' declared with attribute error: 'sendto' called with size bigger than buffer
+ // CLANG: error: 'sendto' called with size bigger than buffer
sendto(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), sizeof(sockaddr_in));
}
@@ -325,7 +376,23 @@
char buf[4] = {0};
// NOLINTNEXTLINE(whitespace/line_length)
- // GCC: error: call to '__sendto_error' declared with attribute error: sendto called with size bigger than buffer
- // CLANG: error: call to unavailable function 'send': send called with size bigger than buffer
+ // GCC: error: call to '__sendto_error' declared with attribute error: 'sendto' called with size bigger than buffer
+ // CLANG: error: 'send' called with size bigger than buffer
send(0, buf, 6, 0);
}
+
+void test_realpath() {
+ char buf[4] = {0};
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // GCC: error: call to '__realpath_size_error' declared with attribute error: 'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // CLANG: error: 'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes
+ realpath(".", buf);
+
+ // This is fine.
+ realpath(".", NULL);
+
+ char bigbuf[PATH_MAX];
+ // CLANG: error: 'realpath': NULL path is never correct; flipped arguments?
+ realpath(NULL, bigbuf);
+}
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index 984a657..2946e23 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -985,3 +985,15 @@
timeout.tv_sec = timeout.tv_nsec = 0;
ASSERT_FORTIFY(ppoll(buf, fd_count, &timeout, NULL));
}
+
+TEST_F(DEATHTEST, open_O_CREAT_without_mode_fortified) {
+ int flags = O_CREAT; // Fool the compiler.
+ ASSERT_FORTIFY(open("", flags));
+}
+
+TEST_F(DEATHTEST, open_O_TMPFILE_without_mode_fortified) {
+#if __BIONIC__ // Our glibc is too old for O_TMPFILE.
+ int flags = O_TMPFILE; // Fool the compiler.
+ ASSERT_FORTIFY(open("", flags));
+#endif
+}
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index f8232aa..b8df8e7 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -207,7 +207,14 @@
application = true;
} else {
ASSERT_STREQ("/", pwd->pw_dir);
- ASSERT_FALSE(exist[pwd->pw_uid]);
+ // TODO(b/27999086): fix this check with the OEM range
+ // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
+ // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
+ // yet, so therefore we do not check for uid's in the OEM range.
+ if (!(pwd->pw_uid >= 2900 && pwd->pw_uid <= 2999) &&
+ !(pwd->pw_uid >= 5000 && pwd->pw_uid <= 5999)) {
+ ASSERT_FALSE(exist[pwd->pw_uid]);
+ }
exist[pwd->pw_uid] = true;
}
}
@@ -453,7 +460,14 @@
if (grp->gr_gid >= exist.size()) {
application = true;
} else {
- ASSERT_FALSE(exist[grp->gr_gid]);
+ // TODO(b/27999086): fix this check with the OEM range
+ // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
+ // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
+ // yet, so therefore we do not check for gid's in the OEM range.
+ if (!(grp->gr_gid >= 2900 && grp->gr_gid <= 2999) &&
+ !(grp->gr_gid >= 5000 && grp->gr_gid <= 5999)) {
+ ASSERT_FALSE(exist[grp->gr_gid]);
+ }
exist[grp->gr_gid] = true;
}
}
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index 227b6d1..9dcc000 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -148,12 +148,16 @@
const std::string& GetName() const { return name_; }
- void SetResult(TestResult result) { result_ = result; }
+ void SetResult(TestResult result) {
+ // Native xfails are inherently likely to actually be relying on undefined
+ // behavior/uninitialized memory, and thus likely to pass from time to time
+ // on CTS. Avoid that unpleasantness by just rewriting all xfail failures
+ // as successes. You'll still see the actual failure details.
+ if (GetName().find("xfail") == 0) result = TEST_SUCCESS;
+ result_ = result;
+ }
TestResult GetResult() const { return result_; }
- TestResult GetExpectedResult() const {
- return GetName().find("xfail") == 0 ? TEST_FAILED : TEST_SUCCESS;
- }
void SetTestTime(int64_t elapsed_time_ns) { elapsed_time_ns_ = elapsed_time_ns; }
@@ -208,13 +212,8 @@
return test_list_[test_id].GetResult();
}
- TestResult GetExpectedTestResult(size_t test_id) const {
- VerifyTestId(test_id);
- return test_list_[test_id].GetExpectedResult();
- }
-
bool GetTestSuccess(size_t test_id) const {
- return GetTestResult(test_id) == GetExpectedTestResult(test_id);
+ return GetTestResult(test_id) == TEST_SUCCESS;
}
void SetTestTime(size_t test_id, int64_t elapsed_time_ns) {
@@ -349,7 +348,7 @@
printf("%s", test_output.c_str());
TestResult result = testcase.GetTestResult(test_id);
- if (result == testcase.GetExpectedTestResult(test_id)) {
+ if (result == TEST_SUCCESS) {
ColoredPrintf(COLOR_GREEN, "[ OK ] ");
} else {
ColoredPrintf(COLOR_RED, "[ FAILED ] ");
@@ -366,19 +365,10 @@
static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
TestResult result = testcase.GetTestResult(test_id);
- TestResult expected = testcase.GetExpectedTestResult(test_id);
if (result == TEST_SUCCESS) {
- if (expected == TEST_SUCCESS) {
- ColoredPrintf(COLOR_GREEN, "[ OK ] ");
- } else if (expected == TEST_FAILED) {
- ColoredPrintf(COLOR_RED, "[ XPASS ] ");
- }
+ ColoredPrintf(COLOR_GREEN, "[ OK ] ");
} else if (result == TEST_FAILED) {
- if (expected == TEST_SUCCESS) {
- ColoredPrintf(COLOR_RED, "[ FAILED ] ");
- } else if (expected == TEST_FAILED) {
- ColoredPrintf(COLOR_YELLOW, "[ XFAIL ] ");
- }
+ ColoredPrintf(COLOR_RED, "[ FAILED ] ");
} else if (result == TEST_TIMEOUT) {
ColoredPrintf(COLOR_RED, "[ TIMEOUT ] ");
}
@@ -400,7 +390,6 @@
int64_t elapsed_time_ns) {
std::vector<std::string> fail_test_name_list;
- std::vector<std::string> xpass_test_name_list;
std::vector<std::pair<std::string, int64_t>> timeout_test_list;
// For tests that were slow but didn't time out.
@@ -414,22 +403,14 @@
test_count += testcase.TestCount();
for (size_t i = 0; i < testcase.TestCount(); ++i) {
TestResult result = testcase.GetTestResult(i);
- TestResult expected = testcase.GetExpectedTestResult(i);
if (result == TEST_TIMEOUT) {
timeout_test_list.push_back(
std::make_pair(testcase.GetTestName(i), testcase.GetTestTime(i)));
- } else if (result == expected) {
- if (result == TEST_SUCCESS) {
- ++success_test_count;
- } else {
- ++expected_failure_count;
- }
- } else {
- if (result == TEST_FAILED) {
+ } else if (result == TEST_SUCCESS) {
+ ++success_test_count;
+ if (testcase.GetTestName(i).find(".xfail_") != std::string::npos) ++expected_failure_count;
+ } else if (result == TEST_FAILED) {
fail_test_name_list.push_back(testcase.GetTestName(i));
- } else {
- xpass_test_name_list.push_back(testcase.GetTestName(i));
- }
}
if (result != TEST_TIMEOUT &&
testcase.GetTestTime(i) / 1000000 >= GetSlowThresholdMs(testcase.GetTestName(i))) {
@@ -450,7 +431,7 @@
ColoredPrintf(COLOR_GREEN, "[ PASS ] ");
printf("%zu %s.", success_test_count, (success_test_count == 1) ? "test" : "tests");
if (expected_failure_count > 0) {
- printf(" (%zu expected failure%s)", expected_failure_count,
+ printf(" (%zu expected failure%s.)", expected_failure_count,
(expected_failure_count == 1) ? "" : "s");
}
printf("\n");
@@ -490,18 +471,7 @@
}
}
- // Print tests that should have failed.
- size_t xpass_test_count = xpass_test_name_list.size();
- if (xpass_test_count > 0) {
- ColoredPrintf(COLOR_RED, "[ XPASS ] ");
- printf("%zu %s, listed below:\n", xpass_test_count, (xpass_test_count == 1) ? "test" : "tests");
- for (const auto& name : xpass_test_name_list) {
- ColoredPrintf(COLOR_RED, "[ XPASS ] ");
- printf("%s\n", name.c_str());
- }
- }
-
- if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0 || xpass_test_count > 0) {
+ if (timeout_test_count > 0 || slow_test_count > 0 || fail_test_count > 0) {
printf("\n");
}
@@ -514,9 +484,6 @@
if (fail_test_count > 0) {
printf("%2zu FAILED %s\n", fail_test_count, (fail_test_count == 1) ? "TEST" : "TESTS");
}
- if (xpass_test_count > 0) {
- printf("%2zu SHOULD HAVE FAILED %s\n", xpass_test_count, (xpass_test_count == 1) ? "TEST" : "TESTS");
- }
fflush(stdout);
}
diff --git a/tests/iconv_test.cpp b/tests/iconv_test.cpp
new file mode 100644
index 0000000..b197152
--- /dev/null
+++ b/tests/iconv_test.cpp
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2017 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 <iconv.h>
+
+#define INVALID_ICONV_T reinterpret_cast<iconv_t>(-1)
+
+TEST(iconv, iconv_open_EINVAL) {
+ errno = 0;
+ ASSERT_EQ(INVALID_ICONV_T, iconv_open("silly", "silly"));
+ ASSERT_EQ(EINVAL, errno);
+ errno = 0;
+ ASSERT_EQ(INVALID_ICONV_T, iconv_open("silly", "UTF-8"));
+ ASSERT_EQ(EINVAL, errno);
+ errno = 0;
+ ASSERT_EQ(INVALID_ICONV_T, iconv_open("UTF-8", "silly"));
+ ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(iconv, iconv_open_comparator) {
+ // Examples from http://www.unicode.org/reports/tr22/#Charset_Alias_Matching:
+ // "For example, the following names should match: "UTF-8", "utf8", "u.t.f-008", ..."
+ iconv_t c;
+ ASSERT_NE(INVALID_ICONV_T, c = iconv_open("UTF-8", "utf8"));
+ ASSERT_EQ(0, iconv_close(c));
+ ASSERT_NE(INVALID_ICONV_T, c = iconv_open("UTF-8", "u.t.f-008"));
+ ASSERT_EQ(0, iconv_close(c));
+
+ // "...but not "utf-80" or "ut8"."
+ errno = 0;
+ ASSERT_EQ(INVALID_ICONV_T, iconv_open("UTF-8", "utf-80"));
+ ASSERT_EQ(EINVAL, errno);
+ errno = 0;
+ ASSERT_EQ(INVALID_ICONV_T, iconv_open("UTF-8", "ut80"));
+ ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(iconv, iconv_smoke) {
+ const char* utf8 = "a٦ᄀ"; // U+0666 ٦ 0xd9 0xa6 // U+1100 ᄀ 0xe1 0x84 0x80
+ char buf[BUFSIZ] = {};
+
+ iconv_t c = iconv_open("UTF-32LE", "UTF-8");
+ ASSERT_NE(INVALID_ICONV_T, c);
+
+ char* in = const_cast<char*>(utf8);
+ size_t in_bytes = strlen(in);
+
+ char* out = buf;
+ size_t out_bytes = sizeof(buf);
+
+ EXPECT_EQ(0U, iconv(c, &in, &in_bytes, &out, &out_bytes));
+
+ wchar_t* utf16 = reinterpret_cast<wchar_t*>(buf);
+ EXPECT_EQ(L'a', utf16[0]);
+ EXPECT_EQ(L'٦', utf16[1]);
+ EXPECT_EQ(L'ᄀ', utf16[2]);
+ EXPECT_EQ(L'\0', utf16[3]);
+ EXPECT_EQ(0U, in_bytes);
+ EXPECT_EQ(sizeof(buf) - (3 /* chars */ * 4 /* bytes each */), out_bytes);
+
+ ASSERT_EQ(0, iconv_close(c));
+}
+
+TEST(iconv, iconv_lossy_TRANSLIT) {
+ const char* utf8 = "a٦ᄀz"; // U+0666 ٦ 0xd9 0xa6 // U+1100 ᄀ 0xe1 0x84 0x80
+ char buf[BUFSIZ] = {};
+
+ iconv_t c = iconv_open("ASCII//TRANSLIT", "UTF-8");
+ ASSERT_NE(INVALID_ICONV_T, c);
+
+ char* in = const_cast<char*>(utf8);
+ size_t in_bytes = strlen(in);
+
+ char* out = buf;
+ size_t out_bytes = sizeof(buf);
+
+ // Two of the input characters (5 input bytes) aren't representable as ASCII.
+ // With "//TRANSLIT", we use a replacement character, and report the number
+ // of replacements.
+ EXPECT_EQ(2U, iconv(c, &in, &in_bytes, &out, &out_bytes));
+
+ EXPECT_EQ('a', buf[0]);
+ EXPECT_EQ('?', buf[1]);
+ EXPECT_EQ('?', buf[2]);
+ EXPECT_EQ('z', buf[3]);
+ EXPECT_EQ(0, buf[4]);
+ EXPECT_EQ(0U, in_bytes);
+ EXPECT_EQ(sizeof(buf) - 4, out_bytes);
+
+ ASSERT_EQ(0, iconv_close(c));
+}
+
+TEST(iconv, iconv_lossy_IGNORE) {
+ const char* utf8 = "a٦ᄀz"; // U+0666 ٦ 0xd9 0xa6 // U+1100 ᄀ 0xe1 0x84 0x80
+ char buf[BUFSIZ] = {};
+
+ iconv_t c = iconv_open("ASCII//IGNORE", "UTF-8");
+ ASSERT_NE(INVALID_ICONV_T, c);
+
+ char* in = const_cast<char*>(utf8);
+ size_t in_bytes = strlen(in);
+
+ char* out = buf;
+ size_t out_bytes = sizeof(buf);
+
+ // Two of the input characters (5 input bytes) aren't representable as ASCII.
+ // With "//IGNORE", we just skip them (but return failure).
+ errno = 0;
+ EXPECT_EQ(static_cast<size_t>(-1), iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(EILSEQ, errno);
+
+ EXPECT_EQ('a', buf[0]);
+ EXPECT_EQ('z', buf[1]);
+ EXPECT_EQ(0, buf[2]);
+ EXPECT_EQ(0U, in_bytes);
+ EXPECT_EQ(sizeof(buf) - 2, out_bytes);
+
+ ASSERT_EQ(0, iconv_close(c));
+}
+
+TEST(iconv, iconv_lossy) {
+ const char* utf8 = "a٦ᄀz"; // U+0666 ٦ 0xd9 0xa6 // U+1100 ᄀ 0xe1 0x84 0x80
+ char buf[BUFSIZ] = {};
+
+ iconv_t c = iconv_open("ASCII", "UTF-8");
+ ASSERT_NE(INVALID_ICONV_T, c);
+
+ char* in = const_cast<char*>(utf8);
+ size_t in_bytes = strlen(in);
+
+ char* out = buf;
+ size_t out_bytes = sizeof(buf);
+
+ // The second input character isn't representable as ASCII, so we stop there.
+ errno = 0;
+ EXPECT_EQ(static_cast<size_t>(-1), iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(EILSEQ, errno);
+
+ EXPECT_EQ('a', buf[0]);
+ EXPECT_EQ(0, buf[1]);
+ EXPECT_EQ(6U, in_bytes); // Two bytes for ٦, three bytes for ᄀ, and one byte for z.
+ EXPECT_EQ(sizeof(buf) - 1, out_bytes);
+
+ ASSERT_EQ(0, iconv_close(c));
+}
+
+TEST(iconv, iconv_malformed_sequence_EILSEQ) {
+ const char* utf8 = "a\xd9z"; // 0xd9 is the first byte of the two-byte U+0666 ٦.
+ char buf[BUFSIZ] = {};
+
+ iconv_t c = iconv_open("UTF-8", "UTF-8");
+ ASSERT_NE(INVALID_ICONV_T, c);
+
+ char* in = const_cast<char*>(utf8);
+ size_t in_bytes = strlen(in);
+
+ char* out = buf;
+ size_t out_bytes = sizeof(buf);
+
+ // The second input byte is a malformed character, so we stop there.
+ errno = 0;
+ EXPECT_EQ(static_cast<size_t>(-1), iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(EILSEQ, errno);
+ EXPECT_EQ('\xd9', *in); // *in is left pointing to the start of the invalid sequence.
+ ++in;
+ --in_bytes;
+ errno = 0;
+ EXPECT_EQ(0U, iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(0, errno);
+
+ EXPECT_EQ('a', buf[0]);
+ EXPECT_EQ('z', buf[1]);
+ EXPECT_EQ(0, buf[2]);
+ EXPECT_EQ(0U, in_bytes);
+ EXPECT_EQ(sizeof(buf) - 2, out_bytes);
+
+ ASSERT_EQ(0, iconv_close(c));
+}
+
+TEST(iconv, iconv_incomplete_sequence_EINVAL) {
+ const char* utf8 = "a\xd9"; // 0xd9 is the first byte of the two-byte U+0666 ٦.
+ char buf[BUFSIZ] = {};
+
+ iconv_t c = iconv_open("UTF-8", "UTF-8");
+ ASSERT_NE(INVALID_ICONV_T, c);
+
+ char* in = const_cast<char*>(utf8);
+ size_t in_bytes = strlen(in);
+
+ char* out = buf;
+ size_t out_bytes = sizeof(buf);
+
+ // The second input byte is just the start of a character, and we don't have any more bytes.
+ errno = 0;
+ EXPECT_EQ(static_cast<size_t>(-1), iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(EINVAL, errno);
+ EXPECT_EQ('\xd9', *in); // *in is left pointing to the start of the incomplete sequence.
+
+ EXPECT_EQ('a', buf[0]);
+ EXPECT_EQ(0, buf[1]);
+ EXPECT_EQ(1U, in_bytes);
+ EXPECT_EQ(sizeof(buf) - 1, out_bytes);
+
+ ASSERT_EQ(0, iconv_close(c));
+}
+
+TEST(iconv, iconv_E2BIG) {
+ const char* utf8 = "abc";
+ char buf[BUFSIZ] = {};
+
+ iconv_t c = iconv_open("UTF-8", "UTF-8");
+ ASSERT_NE(INVALID_ICONV_T, c);
+
+ char* in = const_cast<char*>(utf8);
+ size_t in_bytes = strlen(in);
+
+ char* out = buf;
+ size_t out_bytes = 1;
+
+ // We need three bytes, so one isn't enough (but we will make progress).
+ out_bytes = 1;
+ errno = 0;
+ EXPECT_EQ(static_cast<size_t>(-1), iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(E2BIG, errno);
+ EXPECT_EQ(2U, in_bytes);
+ EXPECT_EQ(0U, out_bytes);
+
+ // Two bytes left, so zero isn't enough (and we can't even make progress).
+ out_bytes = 0;
+ errno = 0;
+ EXPECT_EQ(static_cast<size_t>(-1), iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(E2BIG, errno);
+ EXPECT_EQ(2U, in_bytes);
+ EXPECT_EQ(0U, out_bytes);
+
+ // Two bytes left, so one isn't enough (but we will make progress).
+ out_bytes = 1;
+ errno = 0;
+ EXPECT_EQ(static_cast<size_t>(-1), iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(E2BIG, errno);
+ EXPECT_EQ(1U, in_bytes);
+ EXPECT_EQ(0U, out_bytes);
+
+ // One byte left, so one byte is now enough.
+ out_bytes = 1;
+ errno = 0;
+ EXPECT_EQ(0U, iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(0, errno);
+ EXPECT_EQ(0U, in_bytes);
+ EXPECT_EQ(0U, out_bytes);
+
+ EXPECT_EQ('a', buf[0]);
+ EXPECT_EQ('b', buf[1]);
+ EXPECT_EQ('c', buf[2]);
+ EXPECT_EQ(0, buf[3]);
+
+ ASSERT_EQ(0, iconv_close(c));
+}
+
+TEST(iconv, iconv_invalid_converter_EBADF) {
+ char* in = nullptr;
+ char* out = nullptr;
+ size_t in_bytes = 0;
+ size_t out_bytes = 0;
+ errno = 0;
+ ASSERT_EQ(static_cast<size_t>(-1), iconv(INVALID_ICONV_T, &in, &in_bytes, &out, &out_bytes));
+ ASSERT_EQ(EBADF, errno);
+}
+
+TEST(iconv, iconv_close_invalid_converter_EBADF) {
+ errno = 0;
+ ASSERT_EQ(-1, iconv_close(INVALID_ICONV_T));
+ ASSERT_EQ(EBADF, errno);
+}
+
+static void RoundTrip(const char* dst_enc, const char* expected_bytes, size_t n) {
+ // Examples from https://en.wikipedia.org/wiki/UTF-16.
+ const char* utf8 = "$€𐐷"; // U+0024, U+20AC, U+10437.
+
+ iconv_t c = iconv_open(dst_enc, "UTF-8");
+ ASSERT_NE(INVALID_ICONV_T, c) << dst_enc;
+
+ char* in = const_cast<char*>(utf8);
+ size_t in_bytes = strlen(utf8);
+ char buf[BUFSIZ] = {};
+ char* out = buf;
+ size_t out_bytes = sizeof(buf);
+ size_t replacement_count = iconv(c, &in, &in_bytes, &out, &out_bytes);
+
+ // Check we got the bytes we were expecting.
+ for (size_t i = 0; i < n; ++i) {
+ EXPECT_EQ(expected_bytes[i], buf[i]) << i << ' '<< dst_enc;
+ }
+
+ ASSERT_EQ(0, iconv_close(c));
+
+ // We can't round-trip if there were replacements.
+ if (strstr(dst_enc, "ascii")) {
+ GTEST_LOG_(INFO) << "can't round-trip " << dst_enc << "\n";
+ return;
+ }
+ ASSERT_EQ(0U, replacement_count);
+
+ c = iconv_open("UTF-8", dst_enc);
+ ASSERT_NE(INVALID_ICONV_T, c) << dst_enc;
+
+ in = buf;
+ in_bytes = n;
+ char buf2[BUFSIZ] = {};
+ out = buf2;
+ out_bytes = sizeof(buf2);
+ iconv(c, &in, &in_bytes, &out, &out_bytes);
+
+ ASSERT_STREQ(utf8, buf2) << dst_enc;
+
+ ASSERT_EQ(0, iconv_close(c));
+}
+
+TEST(iconv, iconv_round_trip_ascii) {
+ RoundTrip("ascii//TRANSLIT", "$??", 3);
+}
+
+TEST(iconv, iconv_round_trip_utf8) {
+ RoundTrip("utf8", "\x24\xe2\x82\xac\xf0\x90\x90\xb7", 8);
+}
+
+TEST(iconv, iconv_round_trip_utf16be) {
+ RoundTrip("utf16be", "\x00\x24" "\x20\xac" "\xd8\x01\xdc\x37", 8);
+}
+
+TEST(iconv, iconv_round_trip_utf16le) {
+ RoundTrip("utf16le", "\x24\x00" "\xac\x20" "\x01\xd8\x37\xdc", 8);
+}
+
+TEST(iconv, iconv_round_trip_utf32be) {
+ RoundTrip("utf32be", "\x00\x00\x00\x24" "\x00\x00\x20\xac" "\x00\x01\x04\x37", 12);
+}
+
+TEST(iconv, iconv_round_trip_utf32le) {
+ RoundTrip("utf32le", "\x24\x00\x00\x00" "\xac\x20\x00\x00" "\x37\x04\x01\x00", 12);
+}
+
+TEST(iconv, iconv_round_trip_wchar_t) {
+ RoundTrip("wchar_t", "\x24\x00\x00\x00" "\xac\x20\x00\x00" "\x37\x04\x01\x00", 12);
+}
+
+static void Check(int expected_errno, const char* src_enc, const char* src, size_t n) {
+ iconv_t c = iconv_open("wchar_t", src_enc);
+ char* in = const_cast<char*>(src);
+ size_t in_bytes = n;
+ wchar_t out_buf[16];
+ size_t out_bytes = sizeof(out_buf);
+ char* out = reinterpret_cast<char*>(out_buf);
+ errno = 0;
+ ASSERT_EQ(static_cast<size_t>(-1), iconv(c, &in, &in_bytes, &out, &out_bytes));
+ EXPECT_EQ(expected_errno, errno);
+ EXPECT_EQ(0, iconv_close(c));
+}
+
+TEST(iconv, iconv_EILSEQ_ascii) {
+ Check(EILSEQ, "ASCII", "\xac", 1); // > 0x7f, so not ASCII.
+}
+
+TEST(iconv, iconv_EILSEQ_utf8_initial) {
+ Check(EILSEQ, "utf8", "\x82", 1); // Invalid initial byte.
+}
+
+TEST(iconv, iconv_EILSEQ_utf8_non_initial) {
+ Check(EILSEQ, "utf8", "\xe2\xe2\x82", 3); // Invalid second byte.
+}
+
+TEST(iconv, iconv_EILSEQ_utf16be_low_surrogate_first) {
+ Check(EILSEQ, "utf16be", "\xdc\x37" "\xd8\x01", 4);
+}
+
+TEST(iconv, iconv_EILSEQ_utf16le_low_surrogate_first) {
+ Check(EILSEQ, "utf16le", "\x37\xdc" "\x01\xd8", 4);
+}
+
+TEST(iconv, iconv_EINVAL_utf8_short) {
+ Check(EINVAL, "utf8", "\xe2\x82", 2); // Missing final byte of 3-byte sequence.
+}
+
+TEST(iconv, iconv_EINVAL_utf16be_short) {
+ Check(EINVAL, "utf16be", "\x00", 1); // Missing second byte.
+}
+
+TEST(iconv, iconv_EINVAL_utf16be_missing_low_surrogate) {
+ Check(EINVAL, "utf16be", "\xd8\x01", 2);
+}
+
+TEST(iconv, iconv_EINVAL_utf16be_half_low_surrogate) {
+ Check(EINVAL, "utf16be", "\xd8\x01\xdc", 3);
+}
+
+TEST(iconv, iconv_EINVAL_utf16le_short) {
+ Check(EINVAL, "utf16le", "\x24", 1); // Missing second byte.
+}
+
+TEST(iconv, iconv_EINVAL_utf16le_missing_low_surrogate) {
+ Check(EINVAL, "utf16le", "\x01\xd8", 2);
+}
+
+TEST(iconv, iconv_EINVAL_utf16le_half_low_surrogate) {
+ Check(EINVAL, "utf16le", "\x01\xd8\x37", 3);
+}
+
+TEST(iconv, iconv_EINVAL_utf32be_short) {
+ Check(EINVAL, "utf32be", "\x00\x00\x00", 3); // Missing final byte.
+}
+
+TEST(iconv, iconv_EINVAL_utf32le_short) {
+ Check(EINVAL, "utf32le", "\x24\x00\x00", 3); // Missing final byte.
+}
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 973a8d2..c1600cc 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -617,3 +617,59 @@
defaults: ["bionic_testlib_defaults"],
srcs: ["preinit_syscall_test_helper.cpp"],
}
+
+cc_test {
+ name: "ld_preload_test_helper",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_preload_test_helper.cpp"],
+ shared_libs: ["ld_preload_test_helper_lib1"],
+ ldflags: ["-Wl,--rpath,${ORIGIN}/.."],
+}
+
+cc_test_library {
+ name: "ld_preload_test_helper_lib1",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_preload_test_helper_lib1.cpp"],
+}
+
+cc_test_library {
+ name: "ld_preload_test_helper_lib2",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_preload_test_helper_lib2.cpp"],
+}
+
+cc_test {
+ name: "ld_config_test_helper",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_config_test_helper.cpp"],
+ shared_libs: ["ld_config_test_helper_lib1"],
+ ldflags: ["-Wl,--rpath,${ORIGIN}/.."],
+}
+
+cc_test_library {
+ name: "ld_config_test_helper_lib1",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_config_test_helper_lib1.cpp"],
+ shared_libs: ["ld_config_test_helper_lib2"],
+ relative_install_path: "/ns2",
+}
+
+cc_test_library {
+ name: "ld_config_test_helper_lib2",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_config_test_helper_lib2.cpp"],
+ relative_install_path: "/ns2",
+}
+
+cc_test_library {
+ name: "ld_config_test_helper_lib3",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_config_test_helper_lib3.cpp"],
+}
diff --git a/tests/libs/ld_config_test_helper.cpp b/tests/libs/ld_config_test_helper.cpp
new file mode 100644
index 0000000..592e8c0
--- /dev/null
+++ b/tests/libs/ld_config_test_helper.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 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 <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+extern int get_value_from_lib();
+
+int main() {
+ printf("%d", get_value_from_lib());
+ return 0;
+}
diff --git a/tests/libs/ld_config_test_helper_lib1.cpp b/tests/libs/ld_config_test_helper_lib1.cpp
new file mode 100644
index 0000000..fc5401a
--- /dev/null
+++ b/tests/libs/ld_config_test_helper_lib1.cpp
@@ -0,0 +1,4 @@
+extern int get_value_from_another_lib();
+int get_value_from_lib() {
+ return get_value_from_another_lib();
+}
diff --git a/tests/libs/ld_config_test_helper_lib2.cpp b/tests/libs/ld_config_test_helper_lib2.cpp
new file mode 100644
index 0000000..a620a6c
--- /dev/null
+++ b/tests/libs/ld_config_test_helper_lib2.cpp
@@ -0,0 +1,3 @@
+int get_value_from_another_lib() {
+ return 12345;
+}
diff --git a/tests/libs/ld_config_test_helper_lib3.cpp b/tests/libs/ld_config_test_helper_lib3.cpp
new file mode 100644
index 0000000..93d1cd8
--- /dev/null
+++ b/tests/libs/ld_config_test_helper_lib3.cpp
@@ -0,0 +1,3 @@
+int get_value_from_another_lib() {
+ return 54321;
+}
diff --git a/tests/libs/ld_preload_test_helper.cpp b/tests/libs/ld_preload_test_helper.cpp
new file mode 100644
index 0000000..592e8c0
--- /dev/null
+++ b/tests/libs/ld_preload_test_helper.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 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 <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+extern int get_value_from_lib();
+
+int main() {
+ printf("%d", get_value_from_lib());
+ return 0;
+}
diff --git a/tests/libs/ld_preload_test_helper_lib1.cpp b/tests/libs/ld_preload_test_helper_lib1.cpp
new file mode 100644
index 0000000..74e89db
--- /dev/null
+++ b/tests/libs/ld_preload_test_helper_lib1.cpp
@@ -0,0 +1,3 @@
+int get_value_from_lib() {
+ return 12345;
+}
diff --git a/tests/libs/ld_preload_test_helper_lib2.cpp b/tests/libs/ld_preload_test_helper_lib2.cpp
new file mode 100644
index 0000000..9239891
--- /dev/null
+++ b/tests/libs/ld_preload_test_helper_lib2.cpp
@@ -0,0 +1,3 @@
+int get_value_from_lib() {
+ return 54321;
+}
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index a4cffc0..e70528e 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -270,3 +270,34 @@
CPU_FREE(set1);
CPU_FREE(set2);
}
+
+TEST(sched, sched_get_priority_min_sched_get_priority_max) {
+ EXPECT_LE(sched_get_priority_min(SCHED_BATCH), sched_get_priority_max(SCHED_BATCH));
+ EXPECT_LE(sched_get_priority_min(SCHED_FIFO), sched_get_priority_max(SCHED_FIFO));
+ EXPECT_LE(sched_get_priority_min(SCHED_IDLE), sched_get_priority_max(SCHED_IDLE));
+ EXPECT_LE(sched_get_priority_min(SCHED_OTHER), sched_get_priority_max(SCHED_OTHER));
+ EXPECT_LE(sched_get_priority_min(SCHED_RR), sched_get_priority_max(SCHED_RR));
+}
+
+TEST(sched, sched_getscheduler_sched_setscheduler) {
+ // POSIX: "If pid is zero, the scheduling policy shall be returned for the
+ // calling process".
+ ASSERT_EQ(sched_getscheduler(getpid()), sched_getscheduler(0));
+
+ const int original_policy = sched_getscheduler(getpid());
+ sched_param p = {};
+ p.sched_priority = sched_get_priority_min(original_policy);
+ errno = 0;
+ ASSERT_EQ(-1, sched_setscheduler(getpid(), INT_MAX, &p));
+ ASSERT_EQ(EINVAL, errno);
+
+ ASSERT_EQ(0, sched_getparam(getpid(), &p));
+ ASSERT_EQ(original_policy, sched_setscheduler(getpid(), SCHED_BATCH, &p));
+ // POSIX says this should return the previous policy (here SCHED_BATCH),
+ // but the Linux system call doesn't, and the glibc wrapper doesn't correct
+ // this (the "returns 0" behavior is even documented on the man page in
+ // the BUGS section). This was our historical behavior too, so in the
+ // absence of reasons to break compatibility with ourselves and glibc, we
+ // don't behave as POSIX specifies. http://b/26203902.
+ ASSERT_EQ(0, sched_setscheduler(getpid(), original_policy, &p));
+}
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 36ac690..207c156 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -527,3 +527,11 @@
ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
EXPECT_TRUE(sigismember(&set, SIGALRM));
}
+
+TEST(signal, killpg_EINVAL) {
+ // POSIX leaves pgrp <= 1 undefined, but glibc fails with EINVAL for < 0
+ // and passes 0 through to kill(2).
+ errno = 0;
+ ASSERT_EQ(-1, killpg(-1, SIGKILL));
+ ASSERT_EQ(EINVAL, errno);
+}
diff --git a/tests/stdio_ext_test.cpp b/tests/stdio_ext_test.cpp
index 7872567..128e255 100644
--- a/tests/stdio_ext_test.cpp
+++ b/tests/stdio_ext_test.cpp
@@ -116,20 +116,78 @@
}
TEST(stdio_ext, __freadable__fwritable) {
- FILE* fp = fopen("/dev/null", "r");
+ FILE* fp;
+
+ // Read-only.
+ fp = fopen("/dev/null", "r");
ASSERT_TRUE(__freadable(fp));
ASSERT_FALSE(__fwritable(fp));
fclose(fp);
+ // Write-only.
fp = fopen("/dev/null", "w");
ASSERT_FALSE(__freadable(fp));
ASSERT_TRUE(__fwritable(fp));
fclose(fp);
- fp = fopen("/dev/null", "w+");
- ASSERT_TRUE(__freadable(fp));
+ // Append (aka write-only).
+ fp = fopen("/dev/null", "a");
+ ASSERT_FALSE(__freadable(fp));
ASSERT_TRUE(__fwritable(fp));
fclose(fp);
+
+ // The three read-write modes.
+ for (auto read_write_mode : {"r+", "w+", "a+"}) {
+ fp = fopen("/dev/null", read_write_mode);
+ ASSERT_TRUE(__freadable(fp));
+ ASSERT_TRUE(__fwritable(fp));
+ fclose(fp);
+ }
+}
+
+TEST(stdio_ext, __freading__fwriting) {
+ FILE* fp;
+
+ // Append (aka write-only). Never reading. Always writing.
+ fp = fopen("/dev/zero", "a");
+ ASSERT_FALSE(__freading(fp)); // Not reading initially.
+ ASSERT_TRUE(__fwriting(fp)); // Writing initially.
+ ASSERT_TRUE(fputc('x', fp) != EOF);
+ ASSERT_FALSE(__freading(fp)); // Not reading after write.
+ ASSERT_TRUE(__fwriting(fp)); // Still writing after write.
+ fclose(fp);
+
+ // Write-only. Never reading. Always writing.
+ fp = fopen("/dev/zero", "w");
+ ASSERT_FALSE(__freading(fp)); // Not reading initially.
+ ASSERT_TRUE(__fwriting(fp)); // Writing initially.
+ ASSERT_TRUE(fputc('x', fp) != EOF);
+ ASSERT_FALSE(__freading(fp)); // Not reading after write.
+ ASSERT_TRUE(__fwriting(fp)); // Still writing after write.
+ fclose(fp);
+
+ // Read-only. Always reading. Never writing.
+ fp = fopen("/dev/zero", "r");
+ ASSERT_TRUE(__freading(fp)); // Reading initially.
+ ASSERT_FALSE(__fwriting(fp)); // Not writing initially.
+ ASSERT_TRUE(fgetc(fp) == 0);
+ ASSERT_TRUE(__freading(fp)); // Still reading after read.
+ ASSERT_FALSE(__fwriting(fp)); // Still not writing after read.
+ fclose(fp);
+
+ // The three read-write modes.
+ for (auto read_write_mode : {"r+", "w+", "a+"}) {
+ fp = fopen("/dev/zero", read_write_mode);
+ ASSERT_FALSE(__freading(fp)); // Not reading initially.
+ ASSERT_FALSE(__fwriting(fp)); // Not writing initially.
+ ASSERT_TRUE(fgetc(fp) == 0);
+ ASSERT_TRUE(__freading(fp)); // Reading after read.
+ ASSERT_FALSE(__fwriting(fp)); // Not writing after read.
+ ASSERT_TRUE(fputc('x', fp) != EOF);
+ ASSERT_FALSE(__freading(fp)); // Not reading after write.
+ ASSERT_TRUE(__fwriting(fp)); // Writing after write.
+ fclose(fp);
+ }
}
TEST(stdio_ext, __fsetlocking) {
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index da70d21..7b7737d 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -27,6 +27,7 @@
#include <wchar.h>
#include <locale.h>
+#include <string>
#include <vector>
#include "BionicDeathTest.h"
@@ -41,9 +42,29 @@
#define STDIO_DEATHTEST stdio_DeathTest
#endif
+using namespace std::string_literals;
+
class stdio_DeathTest : public BionicDeathTest {};
class stdio_nofortify_DeathTest : public BionicDeathTest {};
+static void SetFileTo(const char* path, const char* content) {
+ FILE* fp;
+ ASSERT_NE(nullptr, fp = fopen(path, "w"));
+ ASSERT_NE(EOF, fputs(content, fp));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+static void AssertFileIs(const char* path, const char* expected) {
+ FILE* fp;
+ ASSERT_NE(nullptr, fp = fopen(path, "r"));
+ char* line = nullptr;
+ size_t length;
+ ASSERT_NE(EOF, getline(&line, &length, fp));
+ ASSERT_EQ(0, fclose(fp));
+ ASSERT_STREQ(expected, line);
+ free(line);
+}
+
static void AssertFileIs(FILE* fp, const char* expected, bool is_fmemopen = false) {
rewind(fp);
@@ -535,6 +556,45 @@
L"[-NAN]", L"[NAN]", L"[+NAN]");
}
+TEST(STDIO_TEST, swprintf) {
+ constexpr size_t nchars = 32;
+ wchar_t buf[nchars];
+
+ ASSERT_EQ(2, swprintf(buf, nchars, L"ab")) << strerror(errno);
+ ASSERT_EQ(std::wstring(L"ab"), buf);
+ ASSERT_EQ(5, swprintf(buf, nchars, L"%s", "abcde"));
+ ASSERT_EQ(std::wstring(L"abcde"), buf);
+
+ // Unlike swprintf(), swprintf() returns -1 in case of truncation
+ // and doesn't necessarily zero-terminate the output!
+ ASSERT_EQ(-1, swprintf(buf, 4, L"%s", "abcde"));
+
+ const char kString[] = "Hello, World";
+ ASSERT_EQ(12, swprintf(buf, nchars, L"%s", kString));
+ ASSERT_EQ(std::wstring(L"Hello, World"), buf);
+ ASSERT_EQ(12, swprintf(buf, 13, L"%s", kString));
+ ASSERT_EQ(std::wstring(L"Hello, World"), buf);
+}
+
+TEST(STDIO_TEST, swprintf_a) {
+ constexpr size_t nchars = 32;
+ wchar_t buf[nchars];
+
+ ASSERT_EQ(20, swprintf(buf, nchars, L"%a", 3.1415926535));
+ ASSERT_EQ(std::wstring(L"0x1.921fb54411744p+1"), buf);
+}
+
+TEST(STDIO_TEST, swprintf_ls) {
+ constexpr size_t nchars = 32;
+ wchar_t buf[nchars];
+
+ static const wchar_t kWideString[] = L"Hello\uff41 World";
+ ASSERT_EQ(12, swprintf(buf, nchars, L"%ls", kWideString));
+ ASSERT_EQ(std::wstring(kWideString), buf);
+ ASSERT_EQ(12, swprintf(buf, 13, L"%ls", kWideString));
+ ASSERT_EQ(std::wstring(kWideString), buf);
+}
+
TEST(STDIO_TEST, snprintf_d_INT_MAX) {
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), "%d", INT_MAX);
@@ -923,7 +983,7 @@
ASSERT_EQ(WEOF, fgetwc(fp));
ASSERT_EQ(EILSEQ, errno);
- fclose(fp);
+ ASSERT_EQ(0, fclose(fp));
}
TEST(STDIO_TEST, fmemopen) {
@@ -934,32 +994,410 @@
ASSERT_NE(EOF, fputs("abc>\n", fp));
fflush(fp);
+ // We wrote to the buffer...
ASSERT_STREQ("<abc>\n", buf);
+ // And can read back from the file.
AssertFileIs(fp, "<abc>\n", true);
- fclose(fp);
+ ASSERT_EQ(0, fclose(fp));
}
-TEST(STDIO_TEST, KNOWN_FAILURE_ON_BIONIC(fmemopen_NULL)) {
+TEST(STDIO_TEST, fmemopen_nullptr) {
FILE* fp = fmemopen(nullptr, 128, "r+");
ASSERT_NE(EOF, fputs("xyz\n", fp));
AssertFileIs(fp, "xyz\n", true);
- fclose(fp);
+ ASSERT_EQ(0, fclose(fp));
}
-TEST(STDIO_TEST, fmemopen_EINVAL) {
+TEST(STDIO_TEST, fmemopen_trailing_NUL_byte) {
+ FILE* fp;
+ char buf[8];
+
+ // POSIX: "When a stream open for writing is flushed or closed, a null byte
+ // shall be written at the current position or at the end of the buffer,
+ // depending on the size of the contents."
+ memset(buf, 'x', sizeof(buf));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w"));
+ // Even with nothing written (and not in truncate mode), we'll flush a NUL...
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ("\0xxxxxxx"s, std::string(buf, buf + sizeof(buf)));
+ // Now write and check that the NUL moves along with our writes...
+ ASSERT_NE(EOF, fputs("hello", fp));
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ("hello\0xx"s, std::string(buf, buf + sizeof(buf)));
+ ASSERT_NE(EOF, fputs("wo", fp));
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ("hellowo\0"s, std::string(buf, buf + sizeof(buf)));
+ ASSERT_EQ(0, fclose(fp));
+
+ // "If a stream open for update is flushed or closed and the last write has
+ // advanced the current buffer size, a null byte shall be written at the end
+ // of the buffer if it fits."
+ memset(buf, 'x', sizeof(buf));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "r+"));
+ // Nothing written yet, so no advance...
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ("xxxxxxxx"s, std::string(buf, buf + sizeof(buf)));
+ ASSERT_NE(EOF, fputs("hello", fp));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_size) {
+ FILE* fp;
char buf[16];
+ memset(buf, 'x', sizeof(buf));
- // Invalid size.
- errno = 0;
- ASSERT_EQ(nullptr, fmemopen(buf, 0, "r+"));
- ASSERT_EQ(EINVAL, errno);
+ // POSIX: "The stream shall also maintain the size of the current buffer
+ // contents; use of fseek() or fseeko() on the stream with SEEK_END shall
+ // seek relative to this size."
- // No '+' with NULL buffer.
+ // "For modes r and r+ the size shall be set to the value given by the size
+ // argument."
+ ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "r"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(16, ftell(fp));
+ EXPECT_EQ(16, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(16, ftell(fp));
+ EXPECT_EQ(16, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "r+"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(16, ftell(fp));
+ EXPECT_EQ(16, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(16, ftell(fp));
+ EXPECT_EQ(16, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+
+ // "For modes w and w+ the initial size shall be zero..."
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "w"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(0, ftell(fp));
+ EXPECT_EQ(0, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(0, ftell(fp));
+ EXPECT_EQ(0, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "w+"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(0, ftell(fp));
+ EXPECT_EQ(0, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(0, ftell(fp));
+ EXPECT_EQ(0, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+
+ // "...and for modes a and a+ the initial size shall be:
+ // 1. Zero, if buf is a null pointer
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "a"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(0, ftell(fp));
+ EXPECT_EQ(0, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(0, ftell(fp));
+ EXPECT_EQ(0, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "a+"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(0, ftell(fp));
+ EXPECT_EQ(0, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(0, ftell(fp));
+ EXPECT_EQ(0, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+
+ // 2. The position of the first null byte in the buffer, if one is found
+ memset(buf, 'x', sizeof(buf));
+ buf[3] = '\0';
+ ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(3, ftell(fp));
+ EXPECT_EQ(3, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(3, ftell(fp));
+ EXPECT_EQ(3, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+ memset(buf, 'x', sizeof(buf));
+ buf[3] = '\0';
+ ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a+"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(3, ftell(fp));
+ EXPECT_EQ(3, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(3, ftell(fp));
+ EXPECT_EQ(3, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+
+ // 3. The value of the size argument, if buf is not a null pointer and no
+ // null byte is found.
+ memset(buf, 'x', sizeof(buf));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(16, ftell(fp));
+ EXPECT_EQ(16, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(16, ftell(fp));
+ EXPECT_EQ(16, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+ memset(buf, 'x', sizeof(buf));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a+"));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(16, ftell(fp));
+ EXPECT_EQ(16, ftello(fp));
+ ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
+ EXPECT_EQ(16, ftell(fp));
+ EXPECT_EQ(16, ftello(fp));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_SEEK_END) {
+ // fseek SEEK_END is relative to the current string length, not the buffer size.
+ FILE* fp;
+ char buf[8];
+ memset(buf, 'x', sizeof(buf));
+ strcpy(buf, "str");
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w+"));
+ ASSERT_NE(EOF, fputs("string", fp));
+ EXPECT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(static_cast<long>(strlen("string")), ftell(fp));
+ EXPECT_EQ(static_cast<off_t>(strlen("string")), ftello(fp));
+ EXPECT_EQ(0, fclose(fp));
+
+ // glibc < 2.22 interpreted SEEK_END the wrong way round (subtracting rather
+ // than adding).
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w+"));
+ ASSERT_NE(EOF, fputs("54321", fp));
+ EXPECT_EQ(0, fseek(fp, -2, SEEK_END));
+ EXPECT_EQ('2', fgetc(fp));
+ EXPECT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_seek_invalid) {
+ char buf[8];
+ memset(buf, 'x', sizeof(buf));
+ FILE* fp = fmemopen(buf, sizeof(buf), "w");
+ ASSERT_TRUE(fp != nullptr);
+
+ // POSIX: "An attempt to seek ... to a negative position or to a position
+ // larger than the buffer size given in the size argument shall fail."
+ // (There's no mention of what errno should be set to, and glibc doesn't
+ // set errno in any of these cases.)
+ EXPECT_EQ(-1, fseek(fp, -2, SEEK_SET));
+ EXPECT_EQ(-1, fseeko(fp, -2, SEEK_SET));
+ EXPECT_EQ(-1, fseek(fp, sizeof(buf) + 1, SEEK_SET));
+ EXPECT_EQ(-1, fseeko(fp, sizeof(buf) + 1, SEEK_SET));
+}
+
+TEST(STDIO_TEST, fmemopen_read_EOF) {
+ // POSIX: "A read operation on the stream shall not advance the current
+ // buffer position beyond the current buffer size."
+ char buf[8];
+ memset(buf, 'x', sizeof(buf));
+ FILE* fp = fmemopen(buf, sizeof(buf), "r");
+ ASSERT_TRUE(fp != nullptr);
+ char buf2[BUFSIZ];
+ ASSERT_EQ(8U, fread(buf2, 1, sizeof(buf2), fp));
+ // POSIX: "Reaching the buffer size in a read operation shall count as
+ // end-of-file.
+ ASSERT_TRUE(feof(fp));
+ ASSERT_EQ(EOF, fgetc(fp));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_read_null_bytes) {
+ // POSIX: "Null bytes in the buffer shall have no special meaning for reads."
+ char buf[] = "h\0e\0l\0l\0o";
+ FILE* fp = fmemopen(buf, sizeof(buf), "r");
+ ASSERT_TRUE(fp != nullptr);
+ ASSERT_EQ('h', fgetc(fp));
+ ASSERT_EQ(0, fgetc(fp));
+ ASSERT_EQ('e', fgetc(fp));
+ ASSERT_EQ(0, fgetc(fp));
+ ASSERT_EQ('l', fgetc(fp));
+ ASSERT_EQ(0, fgetc(fp));
+ // POSIX: "The read operation shall start at the current buffer position of
+ // the stream."
+ char buf2[8];
+ memset(buf2, 'x', sizeof(buf2));
+ ASSERT_EQ(4U, fread(buf2, 1, sizeof(buf2), fp));
+ ASSERT_EQ('l', buf2[0]);
+ ASSERT_EQ(0, buf2[1]);
+ ASSERT_EQ('o', buf2[2]);
+ ASSERT_EQ(0, buf2[3]);
+ for (size_t i = 4; i < sizeof(buf2); ++i) ASSERT_EQ('x', buf2[i]) << i;
+ ASSERT_TRUE(feof(fp));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_write) {
+ FILE* fp;
+ char buf[8];
+
+ // POSIX: "A write operation shall start either at the current position of
+ // the stream (if mode has not specified 'a' as the first character)..."
+ memset(buf, 'x', sizeof(buf));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "r+"));
+ setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
+ ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
+ ASSERT_EQ(' ', fputc(' ', fp));
+ EXPECT_EQ("xx xxxxx", std::string(buf, buf + sizeof(buf)));
+ ASSERT_EQ(0, fclose(fp));
+
+ // "...or at the current size of the stream (if mode had 'a' as the first
+ // character)." (See the fmemopen_size test for what "size" means, but for
+ // mode "a", it's the first NUL byte.)
+ memset(buf, 'x', sizeof(buf));
+ buf[3] = '\0';
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a+"));
+ setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
+ ASSERT_EQ(' ', fputc(' ', fp));
+ EXPECT_EQ("xxx \0xxx"s, std::string(buf, buf + sizeof(buf)));
+ ASSERT_EQ(0, fclose(fp));
+
+ // "If the current position at the end of the write is larger than the
+ // current buffer size, the current buffer size shall be set to the current
+ // position." (See the fmemopen_size test for what "size" means, but to
+ // query it we SEEK_END with offset 0, and then ftell.)
+ memset(buf, 'x', sizeof(buf));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w+"));
+ setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(0, ftell(fp));
+ ASSERT_EQ(' ', fputc(' ', fp));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(1, ftell(fp));
+ ASSERT_NE(EOF, fputs("123", fp));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(4, ftell(fp));
+ EXPECT_EQ(" 123\0xxx"s, std::string(buf, buf + sizeof(buf)));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_write_EOF) {
+ // POSIX: "A write operation on the stream shall not advance the current
+ // buffer size beyond the size given in the size argument."
+ FILE* fp;
+
+ // Scalar writes...
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 4, "w"));
+ setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
+ ASSERT_EQ('x', fputc('x', fp));
+ ASSERT_EQ('x', fputc('x', fp));
+ ASSERT_EQ('x', fputc('x', fp));
+ ASSERT_EQ(EOF, fputc('x', fp)); // Only 3 fit because of the implicit NUL.
+ ASSERT_EQ(0, fclose(fp));
+
+ // Vector writes...
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 4, "w"));
+ setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
+ ASSERT_EQ(3U, fwrite("xxxx", 1, 4, fp));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_initial_position) {
+ // POSIX: "The ... current position in the buffer ... shall be initially
+ // set to either the beginning of the buffer (for r and w modes) ..."
+ char buf[] = "hello\0world";
+ FILE* fp;
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "r"));
+ EXPECT_EQ(0L, ftell(fp));
+ EXPECT_EQ(0, fclose(fp));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w"));
+ EXPECT_EQ(0L, ftell(fp));
+ EXPECT_EQ(0, fclose(fp));
+ buf[0] = 'h'; // (Undo the effects of the above.)
+
+ // POSIX: "...or to the first null byte in the buffer (for a modes)."
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a"));
+ EXPECT_EQ(5L, ftell(fp));
+ EXPECT_EQ(0, fclose(fp));
+
+ // POSIX: "If no null byte is found in append mode, the initial position
+ // shall be set to one byte after the end of the buffer."
+ memset(buf, 'x', sizeof(buf));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a"));
+ EXPECT_EQ(static_cast<long>(sizeof(buf)), ftell(fp));
+ EXPECT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_initial_position_allocated) {
+ // POSIX: "If buf is a null pointer, the initial position shall always be
+ // set to the beginning of the buffer."
+ FILE* fp = fmemopen(nullptr, 128, "a+");
+ ASSERT_TRUE(fp != nullptr);
+ EXPECT_EQ(0L, ftell(fp));
+ EXPECT_EQ(0L, fseek(fp, 0, SEEK_SET));
+ EXPECT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_zero_length) {
+ // POSIX says it's up to the implementation whether or not you can have a
+ // zero-length buffer (but "A future version of this standard may require
+ // support of zero-length buffer streams explicitly"). BSD and glibc < 2.22
+ // agreed that you couldn't, but glibc >= 2.22 allows it for consistency.
+ FILE* fp;
+ char buf[16];
+ ASSERT_NE(nullptr, fp = fmemopen(buf, 0, "r+"));
+ ASSERT_EQ(EOF, fgetc(fp));
+ ASSERT_TRUE(feof(fp));
+ ASSERT_EQ(0, fclose(fp));
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 0, "r+"));
+ ASSERT_EQ(EOF, fgetc(fp));
+ ASSERT_TRUE(feof(fp));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_NE(nullptr, fp = fmemopen(buf, 0, "w+"));
+ setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
+ ASSERT_EQ(EOF, fputc('x', fp));
+ ASSERT_EQ(0, fclose(fp));
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 0, "w+"));
+ setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
+ ASSERT_EQ(EOF, fputc('x', fp));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_write_only_allocated) {
+ // POSIX says fmemopen "may fail if the mode argument does not include a '+'".
+ // BSD fails, glibc doesn't. We side with the more lenient.
+ FILE* fp;
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "r"));
+ ASSERT_EQ(0, fclose(fp));
+ ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "w"));
+ ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_fileno) {
+ // There's no fd backing an fmemopen FILE*.
+ FILE* fp = fmemopen(nullptr, 16, "r");
+ ASSERT_TRUE(fp != nullptr);
errno = 0;
- ASSERT_EQ(nullptr, fmemopen(nullptr, 0, "r"));
- ASSERT_EQ(EINVAL, errno);
+ ASSERT_EQ(-1, fileno(fp));
+ ASSERT_EQ(EBADF, errno);
+ ASSERT_EQ(0, fclose(fp));
+}
+
+TEST(STDIO_TEST, fmemopen_append_after_seek) {
+ // In BSD and glibc < 2.22, append mode didn't force writes to append if
+ // there had been an intervening seek.
+
+ FILE* fp;
+ char buf[] = "hello\0world";
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a"));
+ setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_SET));
+ ASSERT_NE(EOF, fputc('!', fp));
+ EXPECT_EQ("hello!\0orld\0"s, std::string(buf, buf + sizeof(buf)));
+ ASSERT_EQ(0, fclose(fp));
+
+ memcpy(buf, "hello\0world", sizeof(buf));
+ ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a+"));
+ setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_SET));
+ ASSERT_NE(EOF, fputc('!', fp));
+ EXPECT_EQ("hello!\0orld\0"s, std::string(buf, buf + sizeof(buf)));
+ ASSERT_EQ(0, fclose(fp));
}
TEST(STDIO_TEST, open_memstream) {
@@ -1465,3 +1903,62 @@
sprintf(&buf[0], "hello");
ASSERT_EQ(buf, "hello");
}
+
+TEST(STDIO_TEST, fopen_append_mode_and_ftell) {
+ TemporaryFile tf;
+ SetFileTo(tf.filename, "0123456789");
+ FILE* fp = fopen(tf.filename, "a");
+ EXPECT_EQ(10, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
+ EXPECT_EQ(2, ftell(fp));
+ ASSERT_NE(EOF, fputs("xxx", fp));
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fclose(fp));
+ AssertFileIs(tf.filename, "0123456789xxx");
+}
+
+TEST(STDIO_TEST, fdopen_append_mode_and_ftell) {
+ TemporaryFile tf;
+ SetFileTo(tf.filename, "0123456789");
+ int fd = open(tf.filename, O_RDWR);
+ ASSERT_NE(-1, fd);
+ // POSIX: "The file position indicator associated with the new stream is set to the position
+ // indicated by the file offset associated with the file descriptor."
+ ASSERT_EQ(4, lseek(fd, 4, SEEK_SET));
+ FILE* fp = fdopen(fd, "a");
+ EXPECT_EQ(4, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
+ EXPECT_EQ(2, ftell(fp));
+ ASSERT_NE(EOF, fputs("xxx", fp));
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fclose(fp));
+ AssertFileIs(tf.filename, "0123456789xxx");
+}
+
+TEST(STDIO_TEST, freopen_append_mode_and_ftell) {
+ TemporaryFile tf;
+ SetFileTo(tf.filename, "0123456789");
+ FILE* other_fp = fopen("/proc/version", "r");
+ FILE* fp = freopen(tf.filename, "a", other_fp);
+ EXPECT_EQ(10, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
+ EXPECT_EQ(2, ftell(fp));
+ ASSERT_NE(EOF, fputs("xxx", fp));
+ ASSERT_EQ(0, fflush(fp));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
+ EXPECT_EQ(13, ftell(fp));
+ ASSERT_EQ(0, fclose(fp));
+ AssertFileIs(tf.filename, "0123456789xxx");
+}
+
+TEST(STDIO_TEST, constants) {
+ ASSERT_LE(FILENAME_MAX, PATH_MAX);
+ ASSERT_EQ(L_tmpnam, PATH_MAX);
+}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 4c4c102..7d2dc20 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -184,7 +184,9 @@
TEST(stdlib, realpath__NULL_filename) {
errno = 0;
- char* p = realpath(NULL, NULL);
+ // Work around the compile-time error generated by FORTIFY here.
+ const char* path = NULL;
+ char* p = realpath(path, NULL);
ASSERT_TRUE(p == NULL);
ASSERT_EQ(EINVAL, errno);
}
@@ -555,54 +557,6 @@
close(fd);
}
-TEST(stdlib, strtol_EINVAL) {
- errno = 0;
- strtol("123", NULL, -1);
- ASSERT_EQ(EINVAL, errno);
- errno = 0;
- strtol("123", NULL, 1);
- ASSERT_EQ(EINVAL, errno);
- errno = 0;
- strtol("123", NULL, 37);
- ASSERT_EQ(EINVAL, errno);
-}
-
-TEST(stdlib, strtoll_EINVAL) {
- errno = 0;
- strtoll("123", NULL, -1);
- ASSERT_EQ(EINVAL, errno);
- errno = 0;
- strtoll("123", NULL, 1);
- ASSERT_EQ(EINVAL, errno);
- errno = 0;
- strtoll("123", NULL, 37);
- ASSERT_EQ(EINVAL, errno);
-}
-
-TEST(stdlib, strtoul_EINVAL) {
- errno = 0;
- strtoul("123", NULL, -1);
- ASSERT_EQ(EINVAL, errno);
- errno = 0;
- strtoul("123", NULL, 1);
- ASSERT_EQ(EINVAL, errno);
- errno = 0;
- strtoul("123", NULL, 37);
- ASSERT_EQ(EINVAL, errno);
-}
-
-TEST(stdlib, strtoull_EINVAL) {
- errno = 0;
- strtoull("123", NULL, -1);
- ASSERT_EQ(EINVAL, errno);
- errno = 0;
- strtoull("123", NULL, 1);
- ASSERT_EQ(EINVAL, errno);
- errno = 0;
- strtoull("123", NULL, 37);
- ASSERT_EQ(EINVAL, errno);
-}
-
TEST(stdlib, getsubopt) {
char* const tokens[] = {
const_cast<char*>("a"),
@@ -648,3 +602,51 @@
// "mblen() shall ... return 0 (if s points to the null byte)".
EXPECT_EQ(0, mblen("", 1));
}
+
+template <typename T>
+static void CheckStrToInt(T fn(const char* s, char** end, int base)) {
+ char* end_p;
+
+ // Negative base => invalid.
+ errno = 0;
+ ASSERT_EQ(T(0), fn("123", &end_p, -1));
+ ASSERT_EQ(EINVAL, errno);
+
+ // Base 1 => invalid (base 0 means "please guess").
+ errno = 0;
+ ASSERT_EQ(T(0), fn("123", &end_p, 1));
+ ASSERT_EQ(EINVAL, errno);
+
+ // Base > 36 => invalid.
+ errno = 0;
+ ASSERT_EQ(T(0), fn("123", &end_p, 37));
+ ASSERT_EQ(EINVAL, errno);
+
+ // If we see "0x" *not* followed by a hex digit, we shouldn't swallow the 'x'.
+ ASSERT_EQ(T(0), fn("0xy", &end_p, 16));
+ ASSERT_EQ('x', *end_p);
+}
+
+TEST(stdlib, strtol_smoke) {
+ CheckStrToInt(strtol);
+}
+
+TEST(stdlib, strtoll_smoke) {
+ CheckStrToInt(strtoll);
+}
+
+TEST(stdlib, strtoul_smoke) {
+ CheckStrToInt(strtoul);
+}
+
+TEST(stdlib, strtoull_smoke) {
+ CheckStrToInt(strtoull);
+}
+
+TEST(stdlib, strtoimax_smoke) {
+ CheckStrToInt(strtoimax);
+}
+
+TEST(stdlib, strtoumax_smoke) {
+ CheckStrToInt(strtoumax);
+}
diff --git a/tests/uchar_test.cpp b/tests/uchar_test.cpp
index c887f8a..8b29667 100644
--- a/tests/uchar_test.cpp
+++ b/tests/uchar_test.cpp
@@ -280,7 +280,10 @@
char bytes[MB_LEN_MAX];
+ memset(bytes, 1, sizeof(bytes));
EXPECT_EQ(1U, c32rtomb(bytes, L'\0', NULL));
+ EXPECT_EQ('\0', bytes[0]);
+ EXPECT_EQ('\x01', bytes[1]);
memset(bytes, 0, sizeof(bytes));
EXPECT_EQ(1U, c32rtomb(bytes, L'h', NULL));
@@ -408,4 +411,3 @@
GTEST_LOG_(INFO) << "uchar.h is unavailable.\n";
#endif
}
-
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index a81f112..cd51e1b 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -375,7 +375,7 @@
EXPECT_EQ(0, unsetenv("test-variable"));
}
-static void TestFsyncFunction(int (*fn)(int)) {
+static void TestSyncFunction(int (*fn)(int)) {
int fd;
// Can't sync an invalid fd.
@@ -401,10 +401,15 @@
ASSERT_NE(-1, fd = open("/data/local/tmp", O_RDONLY));
EXPECT_EQ(0, fn(fd));
close(fd);
+}
- // But some file systems may choose to be fussy...
+static void TestFsyncFunction(int (*fn)(int)) {
+ TestSyncFunction(fn);
+
+ // But some file systems are fussy about fsync/fdatasync...
errno = 0;
- ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY));
+ int fd = open("/proc/version", O_RDONLY);
+ ASSERT_NE(-1, fd);
EXPECT_EQ(-1, fn(fd));
EXPECT_EQ(EINVAL, errno);
close(fd);
@@ -418,6 +423,10 @@
TestFsyncFunction(fsync);
}
+TEST(UNISTD_TEST, syncfs) {
+ TestSyncFunction(syncfs);
+}
+
static void AssertGetPidCorrect() {
// The loop is just to make manual testing/debugging with strace easier.
pid_t getpid_syscall_result = syscall(__NR_getpid);
@@ -837,6 +846,7 @@
VERIFY_SYSCONF_UNSUPPORTED(_SC_2_FORT_DEV);
VERIFY_SYSCONF_UNSUPPORTED(_SC_2_FORT_RUN);
VERIFY_SYSCONF_UNSUPPORTED(_SC_2_UPE);
+ VERIFY_SYSCONF_POSIX_VERSION(_SC_2_VERSION);
VERIFY_SYSCONF_POSITIVE(_SC_JOB_CONTROL);
VERIFY_SYSCONF_POSITIVE(_SC_SAVED_IDS);
VERIFY_SYSCONF_POSIX_VERSION(_SC_VERSION);
@@ -952,7 +962,6 @@
VERIFY_SYSCONF_UNSUPPORTED(_SC_2_CHAR_TERM);
VERIFY_SYSCONF_UNSUPPORTED(_SC_2_LOCALEDEF);
VERIFY_SYSCONF_UNSUPPORTED(_SC_2_SW_DEV);
- VERIFY_SYSCONF_UNSUPPORTED(_SC_2_VERSION);
VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_CRYPT);
VERIFY_SYSCONF_UNSUPPORTED(_SC_XOPEN_ENH_I18N);
@@ -1372,3 +1381,10 @@
ASSERT_EXIT(execve("/system/bin/run-as", args, envs), testing::ExitedWithCode(1),
"<unknown>: usage: run-as");
}
+
+TEST(UNISTD_TEST, getlogin_r) {
+ char buf[LOGIN_NAME_MAX] = {};
+ EXPECT_EQ(ERANGE, getlogin_r(buf, 0));
+ EXPECT_EQ(0, getlogin_r(buf, sizeof(buf)));
+ EXPECT_STREQ(getlogin(), buf);
+}
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 830eb70..eb23cf3 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -17,6 +17,7 @@
#include <gtest/gtest.h>
#include <errno.h>
+#include <inttypes.h>
#include <limits.h>
#include <locale.h>
#include <stdint.h>
@@ -406,20 +407,98 @@
ASSERT_EQ('\x20', *invalid);
}
-TEST(wchar, wcstol) {
- ASSERT_EQ(123L, wcstol(L"123", NULL, 0));
+template <typename T>
+using WcsToIntFn = T (*)(const wchar_t*, wchar_t**, int);
+
+template <typename T>
+void TestSingleWcsToInt(WcsToIntFn<T> fn, const wchar_t* str, int base,
+ T expected_value, ptrdiff_t expected_len) {
+ wchar_t* p;
+ ASSERT_EQ(expected_value, fn(str, &p, base));
+ ASSERT_EQ(expected_len, p - str) << str;
}
-TEST(wchar, wcstoll) {
- ASSERT_EQ(123LL, wcstol(L"123", NULL, 0));
+template <typename T>
+void TestWcsToInt(WcsToIntFn<T> fn) {
+ TestSingleWcsToInt(fn, L"123", 10, static_cast<T>(123), 3);
+ TestSingleWcsToInt(fn, L"123", 0, static_cast<T>(123), 3);
+ TestSingleWcsToInt(fn, L"123#", 10, static_cast<T>(123), 3);
+ TestSingleWcsToInt(fn, L"01000", 8, static_cast<T>(512), 5);
+ TestSingleWcsToInt(fn, L"01000", 0, static_cast<T>(512), 5);
+ TestSingleWcsToInt(fn, L" 123 45", 0, static_cast<T>(123), 6);
+ TestSingleWcsToInt(fn, L" -123", 0, static_cast<T>(-123), 6);
+ TestSingleWcsToInt(fn, L"0x10000", 0, static_cast<T>(65536), 7);
+}
+
+template <typename T>
+void TestWcsToIntLimits(WcsToIntFn<T> fn, const wchar_t* min_str,
+ const wchar_t* max_str) {
+ if (std::is_signed<T>::value) {
+ ASSERT_EQ(std::numeric_limits<T>::min(), fn(min_str, nullptr, 0)) << min_str;
+ } else {
+ // If the subject sequence begins with a <hyphen-minus>, the value resulting
+ // from the conversion shall be negated.
+ // http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html
+ ASSERT_EQ(std::numeric_limits<T>::max(), fn(min_str, nullptr, 0)) << min_str;
+ }
+ ASSERT_EQ(std::numeric_limits<T>::max(), fn(max_str, nullptr, 0)) << max_str;
+}
+
+TEST(wchar, wcstol) {
+ TestWcsToInt(wcstol);
+}
+
+TEST(wchar, wcstol_limits) {
+ if (sizeof(long) == 8) {
+ TestWcsToIntLimits(wcstol, L"-9223372036854775809", L"9223372036854775808");
+ } else {
+ TestWcsToIntLimits(wcstol, L"-2147483649", L"2147483648");
+ }
}
TEST(wchar, wcstoul) {
- ASSERT_EQ(123UL, wcstoul(L"123", NULL, 0));
+ TestWcsToInt(wcstoul);
+}
+
+TEST(wchar, wcstoul_limits) {
+ if (sizeof(long) == 8) {
+ TestWcsToIntLimits(wcstoul, L"-1", L"18446744073709551616");
+ } else {
+ TestWcsToIntLimits(wcstoul, L"-1", L"4294967296");
+ }
+}
+
+TEST(wchar, wcstoll) {
+ TestWcsToInt(wcstoll);
+}
+
+TEST(wchar, wcstoll_limits) {
+ TestWcsToIntLimits(wcstoll, L"-9223372036854775809", L"9223372036854775808");
}
TEST(wchar, wcstoull) {
- ASSERT_EQ(123ULL, wcstoul(L"123", NULL, 0));
+ TestWcsToInt(wcstoull);
+}
+
+TEST(wchar, wcstoull_limits) {
+ TestWcsToIntLimits(wcstoull, L"-1", L"18446744073709551616");
+}
+
+TEST(wchar, wcstoimax) {
+ TestWcsToInt(wcstoimax);
+}
+
+TEST(wchar, wcstoimax_limits) {
+ TestWcsToIntLimits(wcstoimax, L"-9223372036854775809",
+ L"9223372036854775808");
+}
+
+TEST(wchar, wcstoumax) {
+ TestWcsToInt(wcstoumax);
+}
+
+TEST(wchar, wcstoumax_limits) {
+ TestWcsToIntLimits(wcstoumax, L"-1", L"18446744073709551616");
}
TEST(wchar, mbsnrtowcs) {
@@ -445,6 +524,18 @@
ASSERT_EQ(L'e', dst[1]);
ASSERT_EQ(L'l', dst[2]);
ASSERT_EQ(&s[3], src);
+
+ memset(dst, 0, sizeof(dst));
+ const char* incomplete = "\xc2"; // Incomplete UTF-8 sequence.
+ src = incomplete;
+ errno = 0;
+ ASSERT_EQ(static_cast<size_t>(-1), mbsnrtowcs(dst, &src, SIZE_MAX, 3, nullptr));
+ ASSERT_EQ(EILSEQ, errno);
+
+ src = incomplete;
+ errno = 0;
+ ASSERT_EQ(static_cast<size_t>(-1), mbsnrtowcs(nullptr, &src, SIZE_MAX, 3, nullptr));
+ ASSERT_EQ(EILSEQ, errno);
}
TEST(wchar, wcsftime) {
@@ -679,66 +770,186 @@
}
template <typename T>
-static void CheckWcsToFloat(T fn(const wchar_t* s, wchar_t** end)) {
- FpUlpEq<0, T> pred;
+using WcsToFloatFn = T (*)(const wchar_t*, wchar_t**);
- EXPECT_PRED_FORMAT2(pred, 9.0, fn(L"9.0", nullptr));
- EXPECT_PRED_FORMAT2(pred, 9.0, fn(L"0.9e1", nullptr));
- EXPECT_PRED_FORMAT2(pred, 9.0, fn(L"0x1.2p3", nullptr));
-
- const wchar_t* s = L" \t\v\f\r\n9.0";
+template <typename T>
+void TestSingleWcsToFloat(WcsToFloatFn<T> fn, const wchar_t* str,
+ T expected_value, ptrdiff_t expected_len) {
wchar_t* p;
- EXPECT_PRED_FORMAT2(pred, 9.0, fn(s, &p));
- EXPECT_EQ(s + wcslen(s), p);
-
- EXPECT_TRUE(isnan(fn(L"+nan", nullptr)));
- EXPECT_TRUE(isnan(fn(L"nan", nullptr)));
- EXPECT_TRUE(isnan(fn(L"-nan", nullptr)));
-
- EXPECT_TRUE(isnan(fn(L"+nan(0xff)", nullptr)));
- EXPECT_TRUE(isnan(fn(L"nan(0xff)", nullptr)));
- EXPECT_TRUE(isnan(fn(L"-nan(0xff)", nullptr)));
-
- EXPECT_TRUE(isnan(fn(L"+nanny", &p)));
- EXPECT_STREQ(L"ny", p);
- EXPECT_TRUE(isnan(fn(L"nanny", &p)));
- EXPECT_STREQ(L"ny", p);
- EXPECT_TRUE(isnan(fn(L"-nanny", &p)));
- EXPECT_STREQ(L"ny", p);
-
- EXPECT_EQ(0, fn(L"muppet", &p));
- EXPECT_STREQ(L"muppet", p);
- EXPECT_EQ(0, fn(L" muppet", &p));
- EXPECT_STREQ(L" muppet", p);
-
- EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"+inf", nullptr));
- EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"inf", nullptr));
- EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-inf", nullptr));
-
- EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"+infinity", nullptr));
- EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"infinity", nullptr));
- EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-infinity", nullptr));
-
- EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"+infinitude", &p));
- EXPECT_STREQ(L"initude", p);
- EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"infinitude", &p));
- EXPECT_STREQ(L"initude", p);
- EXPECT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-infinitude", &p));
- EXPECT_STREQ(L"initude", p);
-
- // Check case-insensitivity.
- EXPECT_EQ(std::numeric_limits<T>::infinity(), fn(L"InFiNiTy", nullptr));
- EXPECT_TRUE(isnan(fn(L"NaN", nullptr)));
+ ASSERT_EQ(expected_value, fn(str, &p));
+ ASSERT_EQ(expected_len, p - str);
}
-TEST(wchar, wcstod) {
- CheckWcsToFloat(wcstod);
+template <typename T>
+void TestWcsToFloat(WcsToFloatFn<T> fn) {
+ TestSingleWcsToFloat(fn, L"123", static_cast<T>(123.0L), 3);
+ TestSingleWcsToFloat(fn, L"123#", static_cast<T>(123.0L), 3);
+ TestSingleWcsToFloat(fn, L" 123 45", static_cast<T>(123.0L), 6);
+ TestSingleWcsToFloat(fn, L"9.0", static_cast<T>(9.0L), 3);
+ TestSingleWcsToFloat(fn, L"-9.0", static_cast<T>(-9.0L), 4);
+ TestSingleWcsToFloat(fn, L" \t\v\f\r\n9.0", static_cast<T>(9.0L), 9);
+}
+
+template <typename T>
+void TestWcsToFloatHexFloats(WcsToFloatFn<T> fn) {
+ TestSingleWcsToFloat(fn, L"0.9e1", static_cast<T>(9.0L), 5);
+ TestSingleWcsToFloat(fn, L"0x1.2p3", static_cast<T>(9.0L), 7);
+ TestSingleWcsToFloat(fn, L"+1e+100", static_cast<T>(1e100L), 7);
+ TestSingleWcsToFloat(fn, L"0x10000.80", static_cast<T>(65536.50L), 10);
+}
+
+template <typename T>
+void TestWcsToFloatInfNan(WcsToFloatFn<T> fn) {
+ ASSERT_TRUE(isnan(fn(L"+nan", nullptr)));
+ ASSERT_TRUE(isnan(fn(L"nan", nullptr)));
+ ASSERT_TRUE(isnan(fn(L"-nan", nullptr)));
+
+ ASSERT_TRUE(isnan(fn(L"+nan(0xff)", nullptr)));
+ ASSERT_TRUE(isnan(fn(L"nan(0xff)", nullptr)));
+ ASSERT_TRUE(isnan(fn(L"-nan(0xff)", nullptr)));
+
+ wchar_t* p;
+ ASSERT_TRUE(isnan(fn(L"+nanny", &p)));
+ ASSERT_STREQ(L"ny", p);
+ ASSERT_TRUE(isnan(fn(L"nanny", &p)));
+ ASSERT_STREQ(L"ny", p);
+ ASSERT_TRUE(isnan(fn(L"-nanny", &p)));
+ ASSERT_STREQ(L"ny", p);
+
+ ASSERT_EQ(0, fn(L"muppet", &p));
+ ASSERT_STREQ(L"muppet", p);
+ ASSERT_EQ(0, fn(L" muppet", &p));
+ ASSERT_STREQ(L" muppet", p);
+
+ ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"+inf", nullptr));
+ ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"inf", nullptr));
+ ASSERT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-inf", nullptr));
+
+ ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"+infinity", nullptr));
+ ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"infinity", nullptr));
+ ASSERT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-infinity", nullptr));
+
+ ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"+infinitude", &p));
+ ASSERT_STREQ(L"initude", p);
+ ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"infinitude", &p));
+ ASSERT_STREQ(L"initude", p);
+ ASSERT_EQ(-std::numeric_limits<T>::infinity(), fn(L"-infinitude", &p));
+ ASSERT_STREQ(L"initude", p);
+
+ // Check case-insensitivity.
+ ASSERT_EQ(std::numeric_limits<T>::infinity(), fn(L"InFiNiTy", nullptr));
+ ASSERT_TRUE(isnan(fn(L"NaN", nullptr)));
}
TEST(wchar, wcstof) {
- CheckWcsToFloat(wcstof);
+ TestWcsToFloat(wcstof);
+}
+
+TEST(wchar, wcstof_hex_floats) {
+ TestWcsToFloatHexFloats(wcstof);
+}
+
+TEST(wchar, wcstof_hex_inf_nan) {
+ TestWcsToFloatInfNan(wcstof);
+}
+
+TEST(wchar, wcstod) {
+ TestWcsToFloat(wcstod);
+}
+
+TEST(wchar, wcstod_hex_floats) {
+ TestWcsToFloatHexFloats(wcstod);
+}
+
+TEST(wchar, wcstod_hex_inf_nan) {
+ TestWcsToFloatInfNan(wcstod);
}
TEST(wchar, wcstold) {
- CheckWcsToFloat(wcstold);
+ TestWcsToFloat(wcstold);
+}
+
+TEST(wchar, wcstold_hex_floats) {
+ TestWcsToFloatHexFloats(wcstold);
+}
+
+TEST(wchar, wcstold_hex_inf_nan) {
+ TestWcsToFloatInfNan(wcstold);
+}
+
+static void AssertWcwidthRange(wchar_t begin, wchar_t end, int expected) {
+ for (wchar_t i = begin; i < end; ++i) {
+ EXPECT_EQ(expected, wcwidth(i)) << static_cast<int>(i);
+ }
+}
+
+TEST(wchar, wcwidth_NUL) {
+ // NUL is defined to return 0 rather than -1, despite being a C0 control.
+ EXPECT_EQ(0, wcwidth(0));
+}
+
+TEST(wchar, wcwidth_ascii) {
+ AssertWcwidthRange(0x20, 0x7f, 1); // Non-C0 non-DEL ASCII.
+}
+
+TEST(wchar, wcwidth_controls) {
+ AssertWcwidthRange(0x01, 0x20, -1); // C0 controls.
+ EXPECT_EQ(-1, wcwidth(0x7f)); // DEL.
+ AssertWcwidthRange(0x80, 0xa0, -1); // C1 controls.
+}
+
+TEST(wchar, wcwidth_non_spacing_and_enclosing_marks_and_format) {
+ EXPECT_EQ(0, wcwidth(0x0300)); // Combining grave.
+ EXPECT_EQ(0, wcwidth(0x20dd)); // Combining enclosing circle.
+ EXPECT_EQ(0, wcwidth(0x00ad)); // Soft hyphen (SHY).
+ EXPECT_EQ(0, wcwidth(0x200b)); // Zero width space.
+}
+
+TEST(wchar, wcwidth_cjk) {
+ EXPECT_EQ(2, wcwidth(0x4e00)); // Start of CJK unified block.
+ EXPECT_EQ(2, wcwidth(0x9fff)); // End of CJK unified block.
+ EXPECT_EQ(2, wcwidth(0x3400)); // Start of CJK extension A block.
+ EXPECT_EQ(2, wcwidth(0x4dbf)); // End of CJK extension A block.
+ EXPECT_EQ(2, wcwidth(0x20000)); // Start of CJK extension B block.
+ EXPECT_EQ(2, wcwidth(0x2a6df)); // End of CJK extension B block.
+}
+
+TEST(wchar, wcwidth_korean_combining_jamo) {
+ AssertWcwidthRange(0x1160, 0x1200, 0); // Original range.
+ EXPECT_EQ(0, wcwidth(0xd7b0)); // Newer.
+ EXPECT_EQ(0, wcwidth(0xd7cb));
+}
+
+TEST(wchar, wcwidth_korean_jeongeul_syllables) {
+ EXPECT_EQ(2, wcwidth(0xac00)); // Start of block.
+ EXPECT_EQ(2, wcwidth(0xd7a3)); // End of defined code points in Unicode 7.
+ // Undefined characters at the end of the block have width 1.
+}
+
+TEST(wchar, wcwidth_kana) {
+ // Hiragana (most, not undefined).
+ AssertWcwidthRange(0x3041, 0x3097, 2);
+ // Katakana.
+ AssertWcwidthRange(0x30a0, 0x3100, 2);
+}
+
+TEST(wchar, wcwidth_circled_two_digit_cjk) {
+ // Circled two-digit CJK "speed sign" numbers are wide,
+ // though EastAsianWidth is ambiguous.
+ AssertWcwidthRange(0x3248, 0x3250, 2);
+}
+
+TEST(wchar, wcwidth_hexagrams) {
+ // Hexagrams are wide, though EastAsianWidth is neutral.
+ AssertWcwidthRange(0x4dc0, 0x4e00, 2);
+}
+
+TEST(wchar, wcwidth_default_ignorables) {
+ AssertWcwidthRange(0xfff0, 0xfff8, 0); // Unassigned by default ignorable.
+ EXPECT_EQ(0, wcwidth(0xe0000)); // ...through 0xe0fff.
+}
+
+TEST(wchar, wcwidth_korean_common_non_syllables) {
+ EXPECT_EQ(2, wcwidth(L'ㅜ')); // Korean "crying" emoticon.
+ EXPECT_EQ(2, wcwidth(L'ㅋ')); // Korean "laughing" emoticon.
}
diff --git a/tools/versioner/src/Driver.cpp b/tools/versioner/src/Driver.cpp
index 1b631b6..8a8e00a 100644
--- a/tools/versioner/src/Driver.cpp
+++ b/tools/versioner/src/Driver.cpp
@@ -100,11 +100,12 @@
std::vector<std::string> cmd = { "versioner" };
cmd.push_back("-std=c11");
cmd.push_back("-x");
- cmd.push_back("c-header");
+ cmd.push_back("c");
cmd.push_back("-fsyntax-only");
cmd.push_back("-Wall");
cmd.push_back("-Wextra");
+ cmd.push_back("-Weverything");
cmd.push_back("-Werror");
cmd.push_back("-Wundef");
cmd.push_back("-Wno-unused-macros");
@@ -118,7 +119,14 @@
cmd.push_back("-DANDROID");
cmd.push_back("-D__ANDROID_API__="s + std::to_string(type.api_level));
+ // FIXME: Re-enable FORTIFY properly once our clang in external/ is new enough
+ // to support diagnose_if without giving us syntax errors.
+#if 0
cmd.push_back("-D_FORTIFY_SOURCE=2");
+#else
+ cmd.push_back("-D_FORTIFY_SOURCE=0");
+ cmd.push_back("-D__BIONIC_DECLARE_FORTIFY_HELPERS");
+#endif
cmd.push_back("-D_GNU_SOURCE");
cmd.push_back("-D_FILE_OFFSET_BITS="s + std::to_string(type.file_offset_bits));
@@ -134,7 +142,9 @@
cmd.push_back(dir);
}
+ cmd.push_back("-include");
cmd.push_back(filename_placeholder);
+ cmd.push_back("-");
auto diags = constructDiags();
driver::Driver driver("versioner", llvm::sys::getDefaultTargetTriple(), *diags, vfs);
diff --git a/tools/versioner/src/Preprocessor.cpp b/tools/versioner/src/Preprocessor.cpp
index 757a392..a7f289b 100644
--- a/tools/versioner/src/Preprocessor.cpp
+++ b/tools/versioner/src/Preprocessor.cpp
@@ -300,7 +300,7 @@
};
auto nextCol = [&file_lines, ¤t_location, &nextLine]() {
- if (current_location.column == file_lines[current_location.column - 1].length()) {
+ if (current_location.column == file_lines[current_location.line - 1].length()) {
nextLine();
} else {
++current_location.column;
diff --git a/tools/versioner/src/Utils.cpp b/tools/versioner/src/Utils.cpp
index ef7facc..ca186a4 100644
--- a/tools/versioner/src/Utils.cpp
+++ b/tools/versioner/src/Utils.cpp
@@ -37,7 +37,8 @@
return buf;
}
-std::vector<std::string> collectHeaders(const std::string& directory) {
+std::vector<std::string> collectHeaders(const std::string& directory,
+ const std::unordered_set<std::string>& ignored_directories) {
std::vector<std::string> headers;
char* dir_argv[2] = { const_cast<char*>(directory.c_str()), nullptr };
@@ -48,16 +49,34 @@
err(1, "failed to open directory '%s'", directory.c_str());
}
+ FTSENT* skipping = nullptr;
while (FTSENT* ent = fts_read(fts.get())) {
- if (ent->fts_info & (FTS_D | FTS_DP)) {
+ if (ent->fts_info & FTS_DP) {
+ if (ent == skipping) {
+ skipping = nullptr;
+ }
continue;
}
- if (!android::base::EndsWith(ent->fts_path, ".h")) {
+ if (skipping != nullptr) {
continue;
}
- headers.push_back(ent->fts_path);
+ if (ent->fts_info & FTS_D) {
+ if (ignored_directories.count(ent->fts_path) != 0) {
+ // fts_read guarantees that `ent` is valid and sane to hold on to until
+ // after it's returned with FTS_DP set.
+ skipping = ent;
+ }
+ continue;
+ }
+
+ std::string path = ent->fts_path;
+ if (!android::base::EndsWith(path, ".h")) {
+ continue;
+ }
+
+ headers.push_back(std::move(path));
}
return headers;
diff --git a/tools/versioner/src/Utils.h b/tools/versioner/src/Utils.h
index 44a34f8..9b45dcd 100644
--- a/tools/versioner/src/Utils.h
+++ b/tools/versioner/src/Utils.h
@@ -22,12 +22,14 @@
#include <unistd.h>
#include <string>
+#include <unordered_set>
#include <vector>
#include <llvm/ADT/StringRef.h>
std::string getWorkingDir();
-std::vector<std::string> collectHeaders(const std::string& directory);
+std::vector<std::string> collectHeaders(const std::string& directory,
+ const std::unordered_set<std::string>& ignored_directories);
static inline std::string dirname(const std::string& path) {
std::unique_ptr<char, decltype(&free)> path_copy(strdup(path.c_str()), free);
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index 735ea04..8db75d7 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -18,6 +18,7 @@
#include <err.h>
#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -44,6 +45,7 @@
#include <android-base/file.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
+#include <android-base/strings.h>
#include "Arch.h"
#include "DeclarationDatabase.h"
@@ -78,11 +80,21 @@
#endif
}
-static CompilationRequirements collectRequirements(const Arch& arch, const std::string& header_dir,
- const std::string& dependency_dir) {
- std::vector<std::string> headers = collectHeaders(header_dir);
- std::vector<std::string> dependencies = { header_dir };
- if (!dependency_dir.empty()) {
+namespace {
+struct HeaderLocationInformation {
+ std::string header_dir;
+ std::string dependency_dir;
+ // Absolute paths to ignore all children -- including subdirectories -- of.
+ std::unordered_set<std::string> ignored_directories;
+};
+}
+
+static CompilationRequirements collectRequirements(const Arch& arch,
+ const HeaderLocationInformation& location) {
+ std::vector<std::string> headers =
+ collectHeaders(location.header_dir, location.ignored_directories);
+ std::vector<std::string> dependencies = { location.header_dir };
+ if (!location.dependency_dir.empty()) {
auto collect_children = [&dependencies](const std::string& dir_path) {
DIR* dir = opendir(dir_path.c_str());
if (!dir) {
@@ -113,8 +125,8 @@
closedir(dir);
};
- collect_children(dependency_dir + "/common");
- collect_children(dependency_dir + "/" + to_string(arch));
+ collect_children(location.dependency_dir + "/common");
+ collect_children(location.dependency_dir + "/" + to_string(arch));
}
auto new_end = std::remove_if(headers.begin(), headers.end(), [&arch](llvm::StringRef header) {
@@ -158,13 +170,12 @@
}
static std::unique_ptr<HeaderDatabase> compileHeaders(const std::set<CompilationType>& types,
- const std::string& header_dir,
- const std::string& dependency_dir) {
+ const HeaderLocationInformation& location) {
if (types.empty()) {
errx(1, "compileHeaders received no CompilationTypes");
}
- auto vfs = createCommonVFS(header_dir, dependency_dir, add_include);
+ auto vfs = createCommonVFS(location.header_dir, location.dependency_dir, add_include);
size_t thread_count = max_thread_count;
std::vector<std::thread> threads;
@@ -175,7 +186,7 @@
auto result = std::make_unique<HeaderDatabase>();
for (const auto& type : types) {
if (requirements.count(type.arch) == 0) {
- requirements[type.arch] = collectRequirements(type.arch, header_dir, dependency_dir);
+ requirements[type.arch] = collectRequirements(type.arch, location);
}
}
@@ -190,6 +201,21 @@
}
}
+ // Dup an empty file to stdin, so that we can use `clang -include a.h -` instead of `clang a.h`,
+ // since some warnings don't get generated in files that are compiled directly.
+ FILE* empty_file = tmpfile();
+ if (!empty_file) {
+ err(1, "failed to create temporary file");
+ }
+
+ int empty_file_fd = fileno(empty_file);
+ if (empty_file_fd == -1) {
+ errx(1, "fileno failed on tmpfile");
+ }
+
+ dup2(empty_file_fd, STDIN_FILENO);
+ fclose(empty_file);
+
thread_count = std::min(thread_count, jobs.size());
if (thread_count == 1) {
@@ -438,6 +464,7 @@
fprintf(stderr, " -f\t\tpreprocess header files even if validation fails\n");
fprintf(stderr, "\n");
fprintf(stderr, "Miscellaneous:\n");
+ fprintf(stderr, " -F\t\tdo not ignore FORTIFY headers by default\n");
fprintf(stderr, " -d\t\tdump function availability\n");
fprintf(stderr, " -j THREADS\tmaximum number of threads to use\n");
fprintf(stderr, " -v\t\tenable verbose logging\n");
@@ -461,9 +488,10 @@
std::string preprocessor_output_path;
bool force = false;
bool dump = false;
+ bool ignore_fortify_headers = true;
int c;
- while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhi")) != -1) {
+ while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhFi")) != -1) {
default_args = false;
switch (c) {
case 'a': {
@@ -549,6 +577,10 @@
add_include = true;
break;
+ case 'F':
+ ignore_fortify_headers = false;
+ break;
+
default:
usage();
break;
@@ -559,8 +591,7 @@
usage();
}
- std::string header_dir;
- std::string dependency_dir;
+ HeaderLocationInformation location;
const char* top = getenv("ANDROID_BUILD_TOP");
if (!top && (optind == argc || add_include)) {
@@ -571,21 +602,32 @@
if (optind == argc) {
// Neither HEADER_PATH nor DEPS_PATH were specified, so try to figure them out.
std::string versioner_dir = to_string(top) + "/bionic/tools/versioner";
- header_dir = versioner_dir + "/current";
- dependency_dir = versioner_dir + "/dependencies";
+ location.header_dir = versioner_dir + "/current";
+ location.dependency_dir = versioner_dir + "/dependencies";
if (platform_dir.empty()) {
platform_dir = versioner_dir + "/platforms";
}
} else {
- if (!android::base::Realpath(argv[optind], &header_dir)) {
+ if (!android::base::Realpath(argv[optind], &location.header_dir)) {
err(1, "failed to get realpath for path '%s'", argv[optind]);
}
if (argc - optind == 2) {
- dependency_dir = argv[optind + 1];
+ location.dependency_dir = argv[optind + 1];
}
}
+ // Every file that lives in bits/fortify is logically a part of a header outside of bits/fortify.
+ // This makes the files there impossible to build on their own.
+ if (ignore_fortify_headers) {
+ std::string fortify_path = location.header_dir;
+ if (!android::base::EndsWith(location.header_dir, "/")) {
+ fortify_path += '/';
+ }
+ fortify_path += "bits/fortify";
+ location.ignored_directories.insert(std::move(fortify_path));
+ }
+
if (selected_levels.empty()) {
selected_levels = supported_levels;
}
@@ -596,10 +638,10 @@
struct stat st;
- if (stat(header_dir.c_str(), &st) != 0) {
- err(1, "failed to stat '%s'", header_dir.c_str());
+ if (const char *dir = location.header_dir.c_str(); stat(dir, &st) != 0) {
+ err(1, "failed to stat '%s'", dir);
} else if (!S_ISDIR(st.st_mode)) {
- errx(1, "'%s' is not a directory", header_dir.c_str());
+ errx(1, "'%s' is not a directory", dir);
}
std::set<CompilationType> compilation_types;
@@ -615,7 +657,7 @@
auto start = std::chrono::high_resolution_clock::now();
std::unique_ptr<HeaderDatabase> declaration_database =
- compileHeaders(compilation_types, header_dir, dependency_dir);
+ compileHeaders(compilation_types, location);
auto end = std::chrono::high_resolution_clock::now();
if (verbose) {
@@ -625,7 +667,7 @@
bool failed = false;
if (dump) {
- declaration_database->dump(header_dir + "/");
+ declaration_database->dump(location.header_dir + "/");
} else {
if (!sanityCheck(declaration_database.get())) {
printf("versioner: sanity check failed\n");
@@ -641,7 +683,7 @@
}
if (!preprocessor_output_path.empty() && (force || !failed)) {
- failed = !preprocessHeaders(preprocessor_output_path, header_dir, declaration_database.get());
+ failed = !preprocessHeaders(preprocessor_output_path, location.header_dir, declaration_database.get());
}
return failed;
}