Merge "Disable MemtagNoteTest#SEGV for native bridge" into android13-tests-dev am: 2934645119
Original change: https://android-review.googlesource.com/c/platform/bionic/+/2290233
Change-Id: I4dc944e20df86d16f51e1c168ba44e2a19801b84
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/README.md b/README.md
index f397fee..85c8190 100644
--- a/README.md
+++ b/README.md
@@ -158,30 +158,63 @@
Adding a system call usually involves:
- 1. Add entries to SYSCALLS.TXT.
+ 1. Add an entry (or entries, in some cases) to SYSCALLS.TXT.
See SYSCALLS.TXT itself for documentation on the format.
- 2. Add constants (and perhaps types) to the appropriate header file.
+ See also the notes below for how to deal with tricky cases like `off_t`.
+ 2. Find the right header file to work in by looking up your system call
+ on [man7.org](https://man7.org/linux/man-pages/dir_section_2.html).
+ (If there's no header file given, see the points above about whether we
+ should really be adding this or not!)
+ 3. Add constants (and perhaps types) to the appropriate header file.
Note that you should check to see whether the constants are already in
kernel uapi header files, in which case you just need to make sure that
- the appropriate POSIX header file in libc/include/ includes the
- relevant file or files.
- 3. Add function declarations to the appropriate header file. Don't forget
- to include the appropriate `__INTRODUCED_IN()`. If you need to create a new
- header file, libc/include/sys/sysinfo.h is a good short example to copy and
- paste from.
- 4. Add basic documentation to the header file. libc/include/sys/sysinfo.h is a
- good short example that shows the expected style. Most of the detail
- should actually be left to the man7.org page, with only a brief
- one-sentence explanation in our documentation. Alway include the return
- value/error reporting details. Explicitly say which version of Android the
- function was added to. Explicitly call out any Android-specific
- changes/additions/limitations because they won't be on the man7.org page.
- 5. Add the function name to the correct section in libc/libc.map.txt.
- 6. Add a basic test. Don't try to test everything; concentrate on just testing
+ the appropriate header file in libc/include/ `#include`s the relevant
+ `linux/` file or files.
+ 4. Add function declarations to the appropriate header file. Don't forget
+ to include the appropriate `__INTRODUCED_IN()`, with the right API level
+ for the first release your system call wrapper will be in. See
+ libc/include/android/api_level.h for the API levels.
+ If the header file doesn't exist, copy all of libc/include/sys/sysinfo.h
+ into your new file --- it's a good short example to start from.
+
+ Note also our style for naming arguments: always use two leading
+ underscores (so developers are free to use any of the unadorned names as
+ macros without breaking things), avoid abbreviations, and ideally try to
+ use the same name as an existing system call (to reduce the amount of
+ English vocabulary required by people who just want to use the function
+ signatures). If there's a similar function already in the C library,
+ check what names it's used. Finally, prefer the `void*` orthography we
+ use over the `void *` you'll see on man7.org.)
+ 5. Add basic documentation to the header file. Again, the existing
+ libc/include/sys/sysinfo.h is a good short example that shows the
+ expected style.
+
+ Most of the detail should actually be left to the man7.org page, with
+ only a brief one-sentence explanation (usually based on the description
+ in the NAME section of the man page) in our documentation. Always
+ include the return value/error reporting details (you can find out
+ what the system call returns from the RETURN VALUE of the man page),
+ but try to match the wording and style wording from _our_ existing
+ documentation; we're trying to minimize the amount of English readers
+ need to understand by using the exact same wording where possible).
+ Explicitly say which version of Android the function was added to in
+ the documentation because the documentation generation tool doesn't yet
+ understand `__INTRODUCED_IN()`.
+
+ Explicitly call out any Android-specific changes/additions/limitations
+ because they won't be on the man7.org page.
+ 6. Add the function name to the correct section in libc/libc.map.txt; it'll
+ be near the end of the file. You may need to add a new section if you're
+ the first to add a system call to this version of Android.
+ 7. Add a basic test. Don't try to test everything; concentrate on just testing
the code that's actually in *bionic*, not all the functionality that's
implemented in the kernel. For simple syscalls, that's just the
auto-generated argument and return value marshalling.
+ Add a test in the right file in tests/. We have one file per header, so if
+ your system call is exposed in <unistd.h>, for example, your test would go
+ in tests/unistd_test.cpp.
+
A trivial test that deliberately supplies an invalid argument helps check
that we're generating the right symbol and have the right declaration in
the header file, and that the change to libc.map.txt from step 5 is
@@ -208,6 +241,39 @@
than 2GiB, say -- so you may end up just writing a "meaningless" program whose
only purpose is to give you patterns to look for when run under strace(1).)
+A general example of adding a system call:
+https://android-review.googlesource.com/c/platform/bionic/+/2073827
+
+### Debugging tips
+1. Key error for a new codename in libc/libc.map.txt
+e.g. what you add in libc/libc.map.txt is:
+
+```
+LIBC_V { # introduced=Vanilla
+ global:
+ xxx; // the new system call you add
+} LIBC_U;
+```
+
+The error output is:
+
+```
+Traceback (most recent call last):
+ File "/path/tp/out/soong/.temp/Soong.python_qucjwd7g/symbolfile/__init__.py", line 171,
+ in decode_api_level_tag
+ decoded = str(decode_api_level(value, api_map))
+ File "/path/to/out/soong/.temp/Soong.python_qucjwd7g/symbolfile/__init__.py", line 157,
+ in decode_api_level
+ return api_map[api]
+KeyError: 'Vanilla'
+```
+
+Solution: Ask in the team and wait for the update.
+
+2. Use of undeclared identifier of the new system call in the test
+Possible Solution: Check everything ready in the files mentioned above first.
+Maybe glibc matters. Follow the example and try #if defined(__GLIBC__).
+
## Updating kernel header files
As mentioned above, this is currently a two-step process:
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 2db0efe..18e8bbc 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -38,6 +38,9 @@
},
{
"name": "memunreachable_unit_test"
+ },
+ {
+ "name": "toybox-tests"
}
],
"hwasan-presubmit": [
@@ -73,6 +76,12 @@
},
{
"name": "malloc_hooks_system_tests"
+ },
+ {
+ "name": "memunreachable_unit_test"
+ },
+ {
+ "name": "toybox-tests"
}
]
}
diff --git a/benchmarks/spawn/AndroidTest.xml b/benchmarks/spawn/AndroidTest.xml
index 466dc7f..5232aa0 100644
--- a/benchmarks/spawn/AndroidTest.xml
+++ b/benchmarks/spawn/AndroidTest.xml
@@ -4,18 +4,18 @@
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
- <option name="push" value="bionic-spawn-benchmarks->/data/local/tmp/bionic-spawn-benchmarks" />
+ <option name="push" value="bionic-spawn-benchmarks->/data/local/tests/unrestricted/bionic-spawn-benchmarks" />
</target_preparer>
<!-- TODO(b/120549168): This seems necessary for consistent results on a walleye, but it's not working with atest
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="push" value="perf-setup.sh->/data/local/tmp/perf-setup.sh" />
- <option name="post-push" value="chmod 755 /data/local/tmp/perf-setup.sh;/data/local/tmp/perf-setup.sh" />
+ <option name="push" value="perf-setup.sh->/data/local/tests/unrestricted/perf-setup.sh" />
+ <option name="post-push" value="chmod 755 /data/local/tests/unrestricted/perf-setup.sh;/data/local/tests/unrestricted/perf-setup.sh" />
</target_preparer>
-->
<test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
- <option name="native-benchmark-device-path" value="/data/local/tmp" />
+ <option name="native-benchmark-device-path" value="/data/local/tests/unrestricted" />
<option name="benchmark-module-name" value="bionic-spawn-benchmarks" />
<!-- The GoogleBenchmarkTest class ordinarily expects every file in the benchmark's
diff --git a/docs/clang_fortify_anatomy.md b/docs/clang_fortify_anatomy.md
new file mode 100644
index 0000000..4b95fdc
--- /dev/null
+++ b/docs/clang_fortify_anatomy.md
@@ -0,0 +1,841 @@
+*This document was originally written for a broad audience, and it was*
+*determined that it'd be good to hold in Bionic's docs, too. Due to the*
+*ever-changing nature of code, it tries to link to a stable tag of*
+*Bionic's libc, rather than the live code in Bionic. Same for Clang.*
+*Reader beware. :)*
+
+# The Anatomy of Clang FORTIFY
+
+## Objective
+
+The intent of this document is to run through the minutiae of how Clang FORTIFY
+actually works in Bionic at the time of writing. Other FORTIFY implementations
+that target Clang should use very similar mechanics. This document exists in part
+because many Clang-specific features serve multiple purposes simultaneously, so
+getting up-to-speed on how things function can be quite difficult.
+
+## Background
+
+FORTIFY is a broad suite of extensions to libc aimed at catching misuses of
+common library functions. Textually, these extensions exist purely in libc, but
+all implementations of FORTIFY rely heavily on C language extensions in order
+to function at all.
+
+Broadly, FORTIFY implementations try to guard against many misuses of C
+standard(-ish) libraries:
+- Buffer overruns in functions where pointers+sizes are passed (e.g., `memcpy`,
+ `poll`), or where sizes exist implicitly (e.g., `strcpy`).
+- Arguments with incorrect values passed to libc functions (e.g.,
+ out-of-bounds bits in `umask`).
+- Missing arguments to functions (e.g., `open()` with `O_CREAT`, but no mode
+ bits).
+
+FORTIFY is traditionally enabled by passing `-D_FORTIFY_SOURCE=N` to your
+compiler. `N==0` disables FORTIFY, whereas `N==1`, `N==2`, and `N==3` enable
+increasingly strict versions of it. In general, FORTIFY doesn't require user
+code changes; that said, some code patterns
+are [incompatible with stricter versions of FORTIFY checking]. This is largely
+because FORTIFY has significant flexibility in what it considers to be an
+"out-of-bounds" access.
+
+FORTIFY implementations use a mix of compiler diagnostics and runtime checks to
+flag and/or mitigate the impacts of the misuses mentioned above.
+
+Further, given FORTIFY's design, the effectiveness of FORTIFY is a function of
+-- among other things -- the optimization level you're compiling your code at.
+Many FORTIFY implementations are implicitly disabled when building with `-O0`,
+since FORTIFY's design for both Clang and GCC relies on optimizations in order
+to provide useful run-time checks. For the purpose of this document, all
+analysis of FORTIFY functions and commentary on builtins assume that code is
+being built with some optimization level > `-O0`.
+
+### A note on GCC
+
+This document talks specifically about Bionic's FORTIFY implementation targeted
+at Clang. While GCC also provides a set of language extensions necessary to
+implement FORTIFY, these tools are different from what Clang offers. This
+divergence is an artifact of Clang and GCC's differing architecture as
+compilers.
+
+Textually, quite a bit can be shared between a FORTIFY implementation for GCC
+and one for Clang (e.g., see [ChromeOS' Glibc patch]), but this kind of sharing
+requires things like macros that expand to unbalanced braces depending on your
+compiler:
+
+```c
+/*
+ * Highly simplified; if you're interested in FORTIFY's actual implementation,
+ * please see the patch linked above.
+ */
+#ifdef __clang__
+# define FORTIFY_PRECONDITIONS
+# define FORTIFY_FUNCTION_END
+#else
+# define FORTIFY_PRECONDITIONS {
+# define FORTIFY_FUNCTION_END }
+#endif
+
+/*
+ * FORTIFY_WARNING_ONLY_IF_SIZE_OF_BUF_LESS_THAN is not defined, due to its
+ * complexity and irrelevance. It turns into a compile-time warning if the
+ * compiler can determine `*buf` has fewer than `size` bytes available.
+ */
+
+char *getcwd(char *buf, size_t size)
+FORTIFY_PRECONDITIONS
+ FORTIFY_WARNING_ONLY_IF_SIZE_OF_BUF_LESS_THAN(buf, size, "`buf` is too smol.")
+{
+ // Actual shared function implementation goes here.
+}
+FORTIFY_FUNCTION_END
+```
+
+All talk of GCC-focused implementations and how to merge Clang and GCC
+implementations is out-of-scope for this doc, however.
+
+## The Life of a Clang FORTIFY Function
+
+As referenced in the Background section, FORTIFY performs many different checks
+for many functions. This section intends to go through real-world examples of
+FORTIFY functions in Bionic, breaking down how each part of these functions
+work, and how the pieces fit together to provide FORTIFY-like functionality.
+
+While FORTIFY implementations may differ between stdlibs, they broadly follow
+the same patterns when implementing their checks for Clang, and they try to
+make similar promises with respect to FORTIFY compiling to be zero-overhead in
+some cases, etc. Moreover, while this document specifically examines Bionic,
+many stdlibs will operate _very similarly_ to Bionic in their Clang FORTIFY
+implementations.
+
+**In general, when reading the below, be prepared for exceptions, subtlety, and
+corner cases. The individual function breakdowns below try to not offer
+redundant information. Each one focuses on different aspects of FORTIFY.**
+
+### Terminology
+
+Because FORTIFY should be mostly transparent to developers, there are inherent
+naming collisions here: `memcpy(x, y, z)` turns into fundamentally different
+generated code depending on the value of `_FORTIFY_SOURCE`. Further, said
+`memcpy` call with `_FORTIFY_SOURCE` enabled needs to be able to refer to the
+`memcpy` that would have been called, had `_FORTIFY_SOURCE` been disabled.
+Hence, the following convention is followed in the subsections below for all
+prose (namely, multiline code blocks are exempted from this):
+
+- Standard library function names preceded by `__builtin_` refer to the use of
+ the function with `_FORTIFY_SOURCE` disabled.
+- Standard library function names without a prefix refer to the use of the
+ function with `_FORTIFY_SOURCE` enabled.
+
+This convention also applies in `clang`. `__builtin_memcpy` will always call
+`memcpy` as though `_FORTIFY_SOURCE` were disabled.
+
+## Breakdown of `mempcpy`
+
+The [FORTIFY'ed version of `mempcpy`] is a full, featureful example of a
+FORTIFY'ed function from Bionic. From the user's perspective, it supports a few
+things:
+- Producing a compile-time error if the number of bytes to copy trivially
+ exceeds the number of bytes available at the destination pointer.
+- If the `mempcpy` has the potential to write to more bytes than what is
+ available at the destination, a run-time check is inserted to crash the
+ program if more bytes are written than what is allowed.
+- Compiling away to be zero overhead when none of the buffer sizes can be
+ determined at compile-time[^1].
+
+The declaration in Bionic's headers for `__builtin_mempcpy` is:
+```c
+void* mempcpy(void* __dst, const void* __src, size_t __n) __INTRODUCED_IN(23);
+```
+
+Which is annotated with nothing special, except for Bionic's versioner, which
+is Android-specific (and orthogonal to FORTIFY anyway), so it will be ignored.
+
+The [source for `mempcpy`] in Bionic's headers for is:
+```c
+__BIONIC_FORTIFY_INLINE
+void* mempcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+ __overloadable
+ __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
+ "'mempcpy' called with size bigger than buffer") {
+#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
+ size_t bos_dst = __bos0(dst);
+ if (!__bos_trivially_ge(bos_dst, copy_amount)) {
+ return __builtin___mempcpy_chk(dst, src, copy_amount, bos_dst);
+ }
+#endif
+ return __builtin_mempcpy(dst, src, copy_amount);
+}
+```
+
+Expanding some of the important macros here, this function expands to roughly:
+```c
+static
+__inline__
+__attribute__((no_stack_protector))
+__attribute__((always_inline))
+void* mempcpy(
+ void* const dst __attribute__((pass_object_size(0))),
+ const void* src,
+ size_t copy_amount)
+ __attribute__((overloadable))
+ __attribute__((diagnose_if(
+ __builtin_object_size(dst, 0) != -1 && __builtin_object_size(dst, 0) <= copy_amount),
+ "'mempcpy' called with size bigger than buffer"))) {
+#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
+ size_t bos_dst = __builtin_object_size(dst, 0);
+ if (!(__bos_trivially_ge(bos_dst, copy_amount))) {
+ return __builtin___mempcpy_chk(dst, src, copy_amount, bos_dst);
+ }
+#endif
+ return __builtin_mempcpy(dst, src, copy_amount);
+}
+```
+
+So let's walk through this step by step, to see how FORTIFY does what it says on
+the tin here.
+
+[^1]: "Zero overhead" in a way [similar to C++11's `std::unique_ptr`]: this will
+turn into a direct call `__builtin_mempcpy` (or an optimized form thereof) with
+no other surrounding checks at runtime. However, the additional complexity may
+hinder optimizations that are performed before the optimizer can prove that the
+`if (...) { ... }` can be optimized out. Depending on how late this happens,
+the additional complexity may skew inlining costs, hide opportunities for e.g.,
+`memcpy` coalescing, etc etc.
+
+### How does Clang select `mempcpy`?
+
+First, it's critical to notice that `mempcpy` is marked `overloadable`. This
+function is a `static inline __attribute__((always_inline))` overload of
+`__builtin_mempcpy`:
+- `__attribute__((overloadable))` allows us to perform overloading in C.
+- `__attribute__((overloadable))` mangles all calls to functions marked with
+ `__attribute__((overloadable))`.
+- `__attribute__((overloadable))` allows exactly one function signature with a
+ given name to not be marked with `__attribute__((overloadable))`. Calls to
+ this overload will not be mangled.
+
+Second, one might note that this `mempcpy` implementation has the same C-level
+signature as `__builtin_mempcpy`. `pass_object_size` is a Clang attribute that
+is generally needed by FORTIFY, but it carries the side-effect that functions
+may be overloaded simply on the presence (or lack of presence) of
+`pass_object_size` attributes. Given two overloads of a function that only
+differ on the presence of `pass_object_size` attributes, the candidate with
+`pass_object_size` attributes is preferred.
+
+Finally, the prior paragraph gets thrown out if one tries to take the address of
+`mempcpy`. It is impossible to take the address of a function with one or more
+parameters that are annotated with `pass_object_size`. Hence,
+`&__builtin_mempcpy == &mempcpy`. Further, because this is an issue of overload
+resolution, `(&mempcpy)(x, y, z);` is functionally identical to
+`__builtin_mempcpy(x, y, z);`.
+
+All of this accomplishes the following:
+- Direct calls to `mempcpy` should call the FORTIFY-protected `mempcpy`.
+- Indirect calls to `&mempcpy` should call `__builtin_mempcpy`.
+
+### How does Clang offer compile-time diagnostics?
+
+Once one is convinced that the FORTIFY-enabled overload of `mempcpy` will be
+selected for direct calls, Clang's `diagnose_if` and `__builtin_object_size` do
+all of the work from there.
+
+Subtleties here primarily fall out of the discussion in the above section about
+`&__builtin_mempcpy == &mempcpy`:
+```c
+#define _FORTIFY_SOURCE 2
+#include <string.h>
+void example_code() {
+ char buf[4]; // ...Assume sizeof(char) == 1.
+ const char input_buf[] = "Hello, World";
+ mempcpy(buf, input_buf, 4); // Valid, no diagnostic issued.
+
+ mempcpy(buf, input_buf, 5); // Emits a compile-time error since sizeof(buf) < 5.
+ __builtin_mempcpy(buf, input_buf, 5); // No compile-time error.
+ (&mempcpy)(buf, input_buf, 5); // No compile-time error, since __builtin_mempcpy is selected.
+}
+```
+
+Otherwise, the rest of this subsection is dedicated to preliminary discussion
+about `__builtin_object_size`.
+
+Clang's frontend can do one of two things with `__builtin_object_size(p, n)`:
+- Evaluate it as a constant.
+ - This can either mean declaring that the number of bytes at `p` is definitely
+ impossible to know, so the default value is used, or the number of bytes at
+ `p` can be known without optimizations.
+- Declare that the expression cannot form a constant, and lower it to
+ `@llvm.objectsize`, which is discussed in depth later.
+
+In the examples above, since `diagnose_if` is evaluated with context from the
+caller, Clang should be able to trivially determine that `buf` refers to a
+`char` array with 4 elements.
+
+The primary consequence of the above is that diagnostics can only be emitted if
+no optimizations are required to detect a broken code pattern. To be specific,
+clang's constexpr evaluator must be able to determine the logical object that
+any given pointer points to in order to fold `__builtin_object_size` to a
+constant, non-default answer:
+
+```c
+#define _FORTIFY_SOURCE 2
+#include <string.h>
+void example_code() {
+ char buf[4]; // ...Assume sizeof(char) == 1.
+ const char input_buf[] = "Hello, World";
+ mempcpy(buf, input_buf, 4); // Valid, no diagnostic issued.
+ mempcpy(buf, input_buf, 5); // Emits a compile-time error since sizeof(buf) < 5.
+ char *buf_ptr = buf;
+ mempcpy(buf_ptr, input_buf, 5); // No compile-time error; `buf_ptr`'s target can't be determined.
+}
+```
+
+### How does Clang insert run-time checks?
+
+This section expands on the following statement: FORTIFY has zero runtime cost
+in instances where there is no chance of catching a bug at run-time. Otherwise,
+it introduces a tiny additional run-time cost to ensure that functions aren't
+misused.
+
+In prior sections, the following was established:
+- `overloadable` and `pass_object_size` prompt Clang to always select this
+ overload of `mempcpy` over `__builtin_mempcpy` for direct calls.
+- If a call to `mempcpy` was trivially broken, Clang would produce a
+ compile-time error, rather than producing a binary.
+
+Hence, the case we're interested in here is one where Clang's frontend selected
+a FORTIFY'ed function's implementation for a function call, but was unable to
+find anything seriously wrong with said function call. Since the frontend is
+powerless to detect bugs at this point, our focus shifts to the mechanisms that
+LLVM uses to support FORTIFY.
+
+Going back to Bionic's `mempcpy` implementation, we have the following (ignoring
+diagnose_if and assuming run-time checks are enabled):
+```c
+static
+__inline__
+__attribute__((no_stack_protector))
+__attribute__((always_inline))
+void* mempcpy(
+ void* const dst __attribute__((pass_object_size(0))),
+ const void* src,
+ size_t copy_amount)
+ __attribute__((overloadable)) {
+ size_t bos_dst = __builtin_object_size(dst, 0);
+ if (bos_dst != -1 &&
+ !(__builtin_constant_p(copy_amount) && bos_dst >= copy_amount)) {
+ return __builtin___mempcpy_chk(dst, src, copy_amount, bos_dst);
+ }
+ return __builtin_mempcpy(dst, src, copy_amount);
+}
+```
+
+In other words, we have a `static`, `always_inline` function which:
+- If `__builtin_object_size(dst, 0)` cannot be determined (in which case, it
+ returns -1), calls `__builtin_mempcpy`.
+- Otherwise, if `copy_amount` can be folded to a constant, and if
+ `__builtin_object_size(dst, 0) >= copy_amount`, calls `__builtin_mempcpy`.
+- Otherwise, calls `__builtin___mempcpy_chk`.
+
+
+How can this be "zero overhead"? Let's focus on the following part of the
+function:
+
+```c
+ size_t bos_dst = __builtin_object_size(dst, 0);
+ if (bos_dst != -1 &&
+ !(__builtin_constant_p(copy_amount) && bos_dst >= copy_amount)) {
+```
+
+If Clang's frontend cannot determine a value for `__builtin_object_size`, Clang
+lowers it to LLVM's `@llvm.objectsize` intrinsic. The `@llvm.objectsize`
+invocation corresponding to `__builtin_object_size(p, 0)` is guaranteed to
+always fold to a constant value by the time LLVM emits machine code.
+
+Hence, `bos_dst` is guaranteed to be a constant; if it's -1, the above branch
+can be eliminated entirely, since it folds to `if (false && ...)`. Further, the
+RHS of the `&&` in this branch has us call `__builtin_mempcpy` if `copy_amount`
+is a known value less than `bos_dst` (yet another constant value). Therefore,
+the entire condition is always knowable when LLVM is done with LLVM IR-level
+optimizations, so no condition is ever emitted to machine code in practice.
+
+#### Why is "zero overhead" in quotes? Why is `unique_ptr` relevant?
+
+`__builtin_object_size` and `__builtin_constant_p` are forced to be constants
+after most optimizations take place. Until LLVM replaces both of these with
+constants and optimizes them out, we have additional branches and function calls
+in our IR. This can have negative effects, such as distorting inlining costs and
+inhibiting optimizations that are conservative around branches in control-flow.
+
+So FORTIFY is free in these cases _in isolation of any of the code around it_.
+Due to its implementation, it may impact the optimizations that occur on code
+around the literal call to the FORTIFY-hardened libc function.
+
+`unique_ptr` was just the first thing that came to the author's mind for "the
+type should be zero cost with any level of optimization enabled, but edge-cases
+might make it only-mostly-free to use."
+
+### How is checking actually performed?
+
+In cases where checking can be performed (e.g., where we call
+`__builtin___mempcpy_chk(dst, src, copy_amount, bos_dst);`), Bionic provides [an
+implementation for `__mempcpy_chk`]. This is:
+
+```c
+extern "C" void* __mempcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
+ __check_count("mempcpy", "count", count);
+ __check_buffer_access("mempcpy", "write into", count, dst_len);
+ return mempcpy(dst, src, count);
+}
+```
+This function itself boils down to a few small branches which abort the program
+if they fail, and a direct call to `__builtin_mempcpy`.
+
+### Wrapping up
+
+In the above breakdown, it was shown how Clang and Bionic work together to:
+- represent FORTIFY-hardened overloads of functions,
+- report misuses of stdlib functions at compile-time, and
+- insert run-time checks for uses of functions that might be incorrect, but only
+ if we have the potential of proving the incorrectness of these.
+
+## Breakdown of open
+
+In Bionic, the [FORTIFY'ed implementation of `open`] is quite large. Much like
+`mempcpy`, the `__builtin_open` declaration is simple:
+
+```c
+int open(const char* __path, int __flags, ...);
+```
+
+With some macros expanded, the FORTIFY-hardened header implementation is:
+```c
+int __open_2(const char*, int);
+int __open_real(const char*, int, ...) __asm__(open);
+
+#define __open_modes_useful(flags) (((flags) & O_CREAT) || ((flags) & O_TMPFILE) == O_TMPFILE)
+
+static
+int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
+ __attribute__((diagnose_if(1, "error", "too many arguments")));
+
+static
+__inline__
+__attribute__((no_stack_protector))
+__attribute__((always_inline))
+int open(const char* const __attribute__((pass_object_size(1))) pathname, int flags)
+ __attribute__((overloadable))
+ __attribute__((diagnose_if(
+ __open_modes_useful(flags),
+ "error",
+ "'open' called with O_CREAT or O_TMPFILE, but missing mode"))) {
+#if __ANDROID_API__ >= 17 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
+ return __open_2(pathname, flags);
+#else
+ return __open_real(pathname, flags);
+#endif
+}
+static
+__inline__
+__attribute__((no_stack_protector))
+__attribute__((always_inline))
+int open(const char* const __attribute__((pass_object_size(1))) pathname, int flags, mode_t modes)
+ __attribute__((overloadable))
+ __clang_warning_if(!__open_modes_useful(flags) && modes,
+ "'open' has superfluous mode bits; missing O_CREAT?") {
+ return __open_real(pathname, flags, modes);
+}
+```
+
+Which may be a lot to take in.
+
+Before diving too deeply, please note that the remainder of these subsections
+assume that the programmer didn't make any egregious typos. Moreover, there's no
+real way that Bionic tries to prevent calls to `open` like
+`open("foo", 0, "how do you convert a const char[N] to mode_t?");`. The only
+real C-compatible solution the author can think of is "stamp out many overloads
+to catch sort-of-common instances of this very uncommon typo." This isn't great.
+
+More directly, no effort is made below to recognize calls that, due to
+incompatible argument types, cannot go to any `open` implementation other than
+`__builtin_open`, since it's recognized right here. :)
+
+### Implementation breakdown
+
+This `open` implementation does a few things:
+- Turns calls to `open` with too many arguments into a compile-time error.
+- Diagnoses calls to `open` with missing modes at compile-time and run-time
+ (both cases turn into errors).
+- Emits warnings on calls to `open` with useless mode bits, unless the mode bits
+ are all 0.
+
+One common bit of code not explained below is the `__open_real` declaration above:
+```c
+int __open_real(const char*, int, ...) __asm__(open);
+```
+
+This exists as a way for us to call `__builtin_open` without needing clang to
+have a pre-defined `__builtin_open` function.
+
+#### Compile-time error on too many arguments
+
+```c
+static
+int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
+ __attribute__((diagnose_if(1, "error", "too many arguments")));
+```
+
+Which matches most calls to open that supply too many arguments, since
+`int(const char *, int, ...)` matches less strongly than
+`int(const char *, int, mode_t, ...)` for calls where the 3rd arg can be
+converted to `mode_t` without too much effort. Because of the `diagnose_if`
+attribute, all of these calls turn into compile-time errors.
+
+#### Compile-time or run-time error on missing arguments
+The following overload handles all two-argument calls to `open`.
+```c
+static
+__inline__
+__attribute__((no_stack_protector))
+__attribute__((always_inline))
+int open(const char* const __attribute__((pass_object_size(1))) pathname, int flags)
+ __attribute__((overloadable))
+ __attribute__((diagnose_if(
+ __open_modes_useful(flags),
+ "error",
+ "'open' called with O_CREAT or O_TMPFILE, but missing mode"))) {
+#if __ANDROID_API__ >= 17 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
+ return __open_2(pathname, flags);
+#else
+ return __open_real(pathname, flags);
+#endif
+}
+```
+
+Like `mempcpy`, `diagnose_if` handles emitting a compile-time error if the call
+to `open` is broken in a way that's visible to Clang's frontend. This
+essentially boils down to "`open` is being called with a `flags` value that
+requires mode bits to be set."
+
+If that fails to catch a bug, we [unconditionally call `__open_2`], which
+performs a run-time check:
+```c
+int __open_2(const char* pathname, int flags) {
+ if (needs_mode(flags)) __fortify_fatal("open: called with O_CREAT/O_TMPFILE but no mode");
+ return FDTRACK_CREATE_NAME("open", __openat(AT_FDCWD, pathname, force_O_LARGEFILE(flags), 0));
+}
+```
+
+#### Compile-time warning if modes are pointless
+
+Finally, we have the following `open` call:
+```c
+static
+__inline__
+__attribute__((no_stack_protector))
+__attribute__((always_inline))
+int open(const char* const __attribute__((pass_object_size(1))) pathname, int flags, mode_t modes)
+ __attribute__((overloadable))
+ __clang_warning_if(!__open_modes_useful(flags) && modes,
+ "'open' has superfluous mode bits; missing O_CREAT?") {
+ return __open_real(pathname, flags, modes);
+}
+```
+
+This simply issues a warning if Clang's frontend can determine that `flags`
+isn't necessary. Due to conventions in existing code, a `modes` value of `0` is
+not diagnosed.
+
+#### What about `&open`?
+One yet-unaddressed aspect of the above is how `&open` works. This is thankfully
+a short answer:
+- It happens that `open` takes a parameter of type `const char*`.
+- It happens that `pass_object_size` -- an attribute only applicable to
+ parameters of type `T*` -- makes it impossible to take the address of a
+ function.
+
+Since clang doesn't support a "this function should never have its address
+taken," attribute, Bionic uses the next best thing: `pass_object_size`. :)
+
+## Breakdown of poll
+
+(Preemptively: at the time of writing, Clang has no literal `__builtin_poll`
+builtin. `__builtin_poll` is referenced below to remain consistent with the
+convention established in the Terminology section.)
+
+Bionic's `poll` implementation is closest to `mempcpy` above, though it has a
+few interesting aspects worth examining.
+
+The [full header implementation of `poll`] is, with some macros expanded:
+```c
+#define __bos_fd_count_trivially_safe(bos_val, fds, fd_count) \
+ ((bos_val) == -1) || \
+ (__builtin_constant_p(fd_count) && \
+ (bos_val) >= sizeof(*fds) * (fd_count)))
+
+static
+__inline__
+__attribute__((no_stack_protector))
+__attribute__((always_inline))
+int poll(struct pollfd* const fds __attribute__((pass_object_size(1))), nfds_t fd_count, int timeout)
+ __attribute__((overloadable))
+ __attriubte__((diagnose_if(
+ __builtin_object_size(fds, 1) != -1 && __builtin_object_size(fds, 1) < sizeof(*fds) * fd_count,
+ "error",
+ "in call to 'poll', fd_count is larger than the given buffer"))) {
+ size_t bos_fds = __builtin_object_size(fds, 1);
+ if (!__bos_fd_count_trivially_safe(bos_fds, fds, fd_count)) {
+ return __poll_chk(fds, fd_count, timeout, bos_fds);
+ }
+ return (&poll)(fds, fd_count, timeout);
+}
+```
+
+To get the commonality with `mempcpy` and `open` out of the way:
+- This function is an overload with `__builtin_poll`.
+- The signature is the same, modulo the presence of a `pass_object_size`
+ attribute. Hence, for direct calls, overload resolution will always prefer it
+ over `__builtin_poll`. Taking the address of `poll` is forbidden, so all
+ references to `&poll` actually reference `__builtin_poll`.
+- When `fds` is too small to hold `fd_count` `pollfd`s, Clang will emit a
+ compile-time error if possible using `diagnose_if`.
+- If this can't be observed until run-time, `__poll_chk` verifies this.
+- When `fds` is a constant according to `__builtin_constant_p`, this always
+ compiles into `__poll_chk` for always-broken calls to `poll`, or
+ `__builtin_poll` for always-safe calls to `poll`.
+
+The critical bits to highlight here are on this line:
+```c
+int poll(struct pollfd* const fds __attribute__((pass_object_size(1))), nfds_t fd_count, int timeout)
+```
+
+And this line:
+```c
+ return (&poll)(fds, fd_count, timeout);
+```
+
+Starting with the simplest, we call `__builtin_poll` with `(&poll)(...);`. As
+referenced above, taking the address of an overloaded function where all but one
+overload has a `pass_object_size` attribute on one or more parameters always
+resolves to the function without any `pass_object_size` attributes.
+
+The other line deserves a section. The subtlety of it is almost entirely in the
+use of `pass_object_size(1)` instead of `pass_object_size(0)`. on the `fds`
+parameter, and the corresponding use of `__builtin_object_size(fds, 1);` in the
+body of `poll`.
+
+### Subtleties of __builtin_object_size(p, N)
+
+Earlier in this document, it was said that a full description of each
+attribute/builtin necessary to power FORTIFY was out of scope. This is... only
+somewhat the case when we talk about `__builtin_object_size` and
+`pass_object_size`, especially when their second argument is `1`.
+
+#### tl;dr
+`__builtin_object_size(p, N)` and `pass_object_size(N)`, where `(N & 1) == 1`,
+can only be accurately determined by Clang. LLVM's `@llvm.objectsize` intrinsic
+ignores the value of `N & 1`, since handling `(N & 1) == 1` accurately requires
+data that's currently entirely inaccessible to LLVM, and that is difficult to
+preserve through LLVM's optimization passes.
+
+`pass_object_size`'s "lifting" of the evaluation of
+`__builtin_object_size(p, N)` to the caller is critical, since it allows Clang
+full visibility into the expression passed to e.g., `poll(&foo->bar, baz, qux)`.
+It's not a perfect solution, but it allows `N == 1` to be fully accurate in at
+least some cases.
+
+#### Background
+Clang's implementation of `__builtin_object_size` aims to be compatible with
+GCC's, which has [a decent bit of documentation]. Put simply,
+`__builtin_object_size(p, N)` is intended to evaluate at compile-time how many
+bytes can be accessed after `p` in a well-defined way. Straightforward examples
+of this are:
+```c
+char buf[8];
+assert(__builtin_object_size(buf, N) == 8);
+assert(__builtin_object_size(buf + 1, N) == 7);
+```
+
+This should hold for all values of N that are valid to pass to
+`__builtin_object_size`. The `N` value of `__builtin_object_size` is a mask of
+settings.
+
+##### (N & 2) == ?
+
+This is mostly for completeness sake; in Bionic's FORTIFY implementation, N is
+always either 0 or 1.
+
+If there are multiple possible values of `p` in a call to
+`__builtin_object_size(p, N)`, the second bit in `N` determines the behavior of
+the compiler. If `(N & 2) == 0`, `__builtin_object_size` should return the
+greatest possible size for each possible value of `p`. Otherwise, it should
+return the least possible value. For example:
+
+```c
+char smol_buf[7];
+char buf[8];
+char *p = rand() ? smol_buf : buf;
+assert(__builtin_object_size(p, 0) == 8);
+assert(__builtin_object_size(p, 2) == 7);
+```
+
+##### (N & 1) == 0
+
+`__builtin_object_size(p, 0)` is more or less as simple as the example in the
+Background section directly above. When Clang attempts to evaluate
+`__builtin_object_size(p, 0);` and when LLVM tries to determine the result of a
+corresponding `@llvm.objectsize` call to, they search for the storage underlying
+the pointer in question. If that can be determined, Clang or LLVM can provide an
+answer; otherwise, they cannot.
+
+##### (N & 1) == 1, and the true magic of pass_object_size
+
+`__builtin_object_size(p, 1)` has a less uniform implementation between LLVM and
+Clang. According to GCC's documentation, "If the least significant bit [of
+__builtin_object_size's second argument] is clear, objects are whole variables,
+if it is set, a closest surrounding subobject is considered the object a pointer
+points to."
+
+The "closest surrounding subobject," means that `(N & 1) == 1` depends on type
+information in order to operate in many cases. Consider the following examples:
+```c
+struct Foo {
+ int a;
+ int b;
+};
+
+struct Foo foo;
+assert(__builtin_object_size(&foo, 0) == sizeof(foo));
+assert(__builtin_object_size(&foo, 1) == sizeof(foo));
+assert(__builtin_object_size(&foo->a, 0) == sizeof(foo));
+assert(__builtin_object_size(&foo->a, 1) == sizeof(int));
+
+struct Foo foos[2];
+assert(__builtin_object_size(&foos[0], 0) == 2 * sizeof(foo));
+assert(__builtin_object_size(&foos[0], 1) == sizeof(foo));
+assert(__builtin_object_size(&foos[0]->a, 0) == 2 * sizeof(foo));
+assert(__builtin_object_size(&foos[0]->a, 1) == sizeof(int));
+```
+
+...And perhaps somewhat surprisingly:
+```c
+void example(struct Foo *foo) {
+ // (As a reminder, `-1` is "I don't know" when `(N & 2) == 0`.)
+ assert(__builtin_object_size(foo, 0) == -1);
+ assert(__builtin_object_size(foo, 1) == -1);
+ assert(__builtin_object_size(foo->a, 0) == -1);
+ assert(__builtin_object_size(foo->a, 1) == sizeof(int));
+}
+```
+
+In Clang, [this type-aware requirement poses problems for us]: Clang's frontend
+knows everything we could possibly want about the types of variables, but
+optimizations are only performed by LLVM. LLVM has no reliable source for C or
+C++ data types, so calls to `__builtin_object_size(p, N)` that cannot be
+resolved by clang are lowered to the equivalent of
+`__builtin_object_size(p, N & ~1)` in LLVM IR.
+
+Moreover, Clang's frontend is the best-equipped part of the compiler to
+accurately determine the answer for `__builtin_object_size(p, N)`, given we know
+what `p` is. LLVM is the best-equipped part of the compiler to determine the
+value of `p`. This ordering issue is unfortunate.
+
+This is where `pass_object_size(N)` comes in. To summarize [the docs for
+`pass_object_size`], it evaluates `__builtin_object_size(p, N)` within the
+context of the caller of the function annotated with `pass_object_size`, and
+passes the value of that into the callee as an invisible parameter. All calls to
+`__builtin_object_size(parameter, N)` are substituted with references to this
+invisible parameter.
+
+Putting this plainly, Clang's frontend struggles to evaluate the following:
+```c
+int foo(void *p) {
+ return __builtin_object_size(p, 1);
+}
+
+void bar() {
+ struct { int i, j } k;
+ // The frontend can't figure this interprocedural objectsize out, so it gets lowered to
+ // LLVM, which determines that the answer here is sizeof(k).
+ int baz = foo(&k.i);
+}
+```
+
+However, with the magic of `pass_object_size`, we get one level of inlining to
+look through:
+```c
+int foo(void *const __attribute__((pass_object_size(1))) p) {
+ return __builtin_object_size(p, 1);
+}
+
+void bar() {
+ struct { int i, j } k;
+ // Due to pass_object_size, this is equivalent to:
+ // int baz = foo(&k.i, __builtin_object_size(&k.i, 1));
+ // ...and `int foo(void *)` is actually equivalent to:
+ // int foo(void *const, size_t size) {
+ // return size;
+ // }
+ int baz = foo(&k.i);
+}
+```
+
+So we can obtain an accurate result in this case.
+
+##### What about pass_object_size(0)?
+It's sort of tangential, but if you find yourself wondering about the utility of
+`pass_object_size(0)` ... it's somewhat split. `pass_object_size(0)` in Bionic's
+FORTIFY exists mostly for visual consistency, simplicity, and as a useful way to
+have e.g., `&mempcpy` == `&__builtin_mempcpy`.
+
+Outside of these fringe benefits, all of the functions with
+`pass_object_size(0)` on parameters are marked with `always_inline`, so
+"lifting" the `__builtin_object_size` call isn't ultimately very helpful. In
+theory, users can always have something like:
+
+```c
+// In some_header.h
+// This function does cool and interesting things with the `__builtin_object_size` of its parameter,
+// and is able to work with that as though the function were defined inline.
+void out_of_line_function(void *__attribute__((pass_object_size(0))));
+```
+
+Though the author isn't aware of uses like this in practice, beyond a few folks
+on LLVM's mailing list seeming interested in trying it someday.
+
+#### Wrapping up
+In the (long) section above, two things were covered:
+- The use of `(&poll)(...);` is a convenient shorthand for calling
+ `__builtin_poll`.
+- `__builtin_object_size(p, N)` with `(N & 1) == 1` is not easy for Clang to
+ answer accurately, since it relies on type info only available in the
+ frontend, and it sometimes relies on optimizations only available in the
+ middle-end. `pass_object_size` helps mitigate this.
+
+## Miscellaneous Notes
+The above should be a roughly comprehensive view of how FORTIFY works in the
+real world. The main thing it fails to mention is the use of [the `diagnose_as_builtin` attribute] in Clang.
+
+As time has moved on, Clang has increasingly gained support for emitting
+warnings that were previously emitted by FORTIFY machinery.
+`diagnose_as_builtin` allows us to remove the `diagnose_if`s from some of the
+`static inline` overloads of stdlib functions above, so Clang may diagnose them
+instead.
+
+Clang's built-in diagnostics are often better than `diagnose_if` diagnostics,
+since Clang can format its diagnostics to include e.g., information about the
+sizes of buffers in a suspect call to a function. `diagnose_if` can only have
+the compiler output constant strings.
+
+[ChromeOS' Glibc patch]: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/90fa9b27731db10a6010c7f7c25b24028145b091/sys-libs/glibc/files/local/glibc-2.33/0007-glibc-add-clang-style-FORTIFY.patch
+[FORTIFY'ed implementation of `open`]: https://android.googlesource.com/platform/bionic/+/refs/heads/android12-release/libc/include/bits/fortify/fcntl.h#41
+[FORTIFY'ed version of `mempcpy`]: https://android.googlesource.com/platform/bionic/+/refs/heads/android12-release/libc/include/bits/fortify/string.h#45
+[a decent bit of documentation]: https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
+[an implementation for `__mempcpy_chk`]: https://android.googlesource.com/platform/bionic/+/refs/heads/android12-release/libc/bionic/fortify.cpp#501
+[full header implementation of `poll`]: https://android.googlesource.com/platform/bionic/+/refs/heads/android12-release/libc/include/bits/fortify/poll.h#43
+[incompatible with stricter versions of FORTIFY checking]: https://godbolt.org/z/fGfEYxfnf
+[similar to C++11's `std::unique_ptr`]: https://stackoverflow.com/questions/58339165/why-can-a-t-be-passed-in-register-but-a-unique-ptrt-cannot
+[source for `mempcpy`]: https://android.googlesource.com/platform/bionic/+/refs/heads/android12-release/libc/include/string.h#55
+[the `diagnose_as_builtin` attribute]: https://releases.llvm.org/14.0.0/tools/clang/docs/AttributeReference.html#diagnose-as-builtin
+[the docs for `pass_object_size`]: https://releases.llvm.org/14.0.0/tools/clang/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size
+[this type-aware requirement poses problems for us]: https://github.com/llvm/llvm-project/issues/55742
+[unconditionally call `__open_2`]: https://android.googlesource.com/platform/bionic/+/refs/heads/android12-release/libc/bionic/open.cpp#70
diff --git a/docs/status.md b/docs/status.md
index bf246a6..20a1309 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -29,6 +29,7 @@
* `gethostid`
* `shm_open`/`shm_unlink`
* `sockatmark`
+ * `ualarm`
Missing functionality:
* `<aio.h>`
@@ -50,6 +51,16 @@
Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/libc/libc.map.txt
+New libc functions in U (API level 34):
+ * `close_range` and `copy_file_range` (Linux-specific GNU extensions).
+ * `memset_explicit` in <string.h> (C23 addition).
+ * `__freadahead` in <stdio_ext.h> (in musl but not glibc).
+
+New libc behavior in U (API level 34):
+ * Support for `%b` and `%B` in the printf/wprintf family, `%b` in the
+ scanf/wscanf family, and `0b` prefixes with base 0 in the strtol/wcstol
+ family.
+
New libc functions in T (API level 33):
* `backtrace`, `backtrace_symbols`, `backtrace_symbols_fd` (`<execinfo.h>`).
* New system call wrappers: `preadv2`, `preadv64v2`, `pwritev2`,
diff --git a/libc/Android.bp b/libc/Android.bp
index 97146aa..6042929 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -35,7 +35,7 @@
"stdio/stdio.cpp",
"stdio/stdio_ext.cpp",
"stdio/vfscanf.cpp",
- "stdio/vfwscanf.c",
+ "stdio/vfwscanf.cpp",
]
// off64_t/time64_t support on LP32.
@@ -95,7 +95,6 @@
header_libs: [
"libc_headers",
- "gwp_asan_headers",
"liblog_headers", // needed by bionic/libc/async_safe/include
],
export_header_lib_headers: [
@@ -198,6 +197,9 @@
arm64: {
srcs: ["arch-arm64/bionic/__set_tls.c"],
},
+ riscv64: {
+ srcs: ["arch-riscv64/bionic/__set_tls.c"],
+ },
x86: {
srcs: [
"arch-x86/bionic/__libc_init_sysinfo.cpp",
@@ -259,18 +261,22 @@
// Include tzsetwall, timelocal, timegm, time2posix, and posix2time.
"-DSTD_INSPIRED",
// Obviously, we want to be thread-safe.
- "-DTHREAD_SAFE",
+ "-DTHREAD_SAFE=1",
// The name of the tm_gmtoff field in our struct tm.
"-DTM_GMTOFF=tm_gmtoff",
+ // TZDEFAULT is not applicable to Android as there is no one file per time zone mapping
+ "-DTZDEFAULT=NULL",
// Where we store our tzdata.
"-DTZDIR=\"/system/usr/share/zoneinfo\"",
// Include `tzname`, `timezone`, and `daylight` globals.
"-DHAVE_POSIX_DECLS=0",
- "-DUSG_COMPAT=1",
+ "-DUSG_COMPAT=2",
+ "-DHAVE_TZNAME=2",
+ // stdbool.h is available
+ "-DHAVE_STDBOOL_H",
// Use the empty string (instead of " ") as the timezone abbreviation
// fallback.
"-DWILDABBR=\"\"",
- "-DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU",
"-Dlint",
],
@@ -372,7 +378,6 @@
"upstream-freebsd/lib/libc/string/wcscat.c",
"upstream-freebsd/lib/libc/string/wcscpy.c",
"upstream-freebsd/lib/libc/string/wmemcmp.c",
- "upstream-freebsd/lib/libc/string/wmemset.c",
],
},
},
@@ -497,13 +502,7 @@
"upstream-openbsd/lib/libc/locale/mbstowcs.c",
"upstream-openbsd/lib/libc/locale/mbtowc.c",
"upstream-openbsd/lib/libc/locale/wcscoll.c",
- "upstream-openbsd/lib/libc/locale/wcstoimax.c",
- "upstream-openbsd/lib/libc/locale/wcstol.c",
- "upstream-openbsd/lib/libc/locale/wcstoll.c",
"upstream-openbsd/lib/libc/locale/wcstombs.c",
- "upstream-openbsd/lib/libc/locale/wcstoul.c",
- "upstream-openbsd/lib/libc/locale/wcstoull.c",
- "upstream-openbsd/lib/libc/locale/wcstoumax.c",
"upstream-openbsd/lib/libc/locale/wcsxfrm.c",
"upstream-openbsd/lib/libc/locale/wctob.c",
"upstream-openbsd/lib/libc/locale/wctomb.c",
@@ -665,6 +664,17 @@
"upstream-openbsd/lib/libc/string/strncmp.c",
],
},
+ riscv64: {
+ srcs: [
+ "arch-riscv64/string/memset_chk.c",
+ "upstream-freebsd/lib/libc/string/memcmp.c",
+ "upstream-freebsd/lib/libc/string/memcpy.c",
+ "upstream-freebsd/lib/libc/string/memmove.c",
+ "upstream-freebsd/lib/libc/string/memset.c",
+ "upstream-openbsd/lib/libc/string/strcmp.c",
+ "upstream-openbsd/lib/libc/string/strlen.c",
+ ],
+ },
x86: {
exclude_srcs: [
"upstream-openbsd/lib/libc/string/memchr.c",
@@ -910,6 +920,16 @@
],
},
+ riscv64: {
+ srcs: [
+ "arch-riscv64/bionic/__bionic_clone.S",
+ "arch-riscv64/bionic/_exit_with_stack_teardown.S",
+ "arch-riscv64/bionic/setjmp.S",
+ "arch-riscv64/bionic/syscall.S",
+ "arch-riscv64/bionic/vfork.S",
+ ],
+ },
+
x86: {
srcs: [
"arch-x86/generic/string/memcmp.S",
@@ -923,24 +943,42 @@
"arch-x86/generic/string/wcscat.c",
"arch-x86/generic/string/wcscpy.c",
"arch-x86/generic/string/wmemcmp.c",
- "arch-x86/generic/string/wmemset.c",
- "arch-x86/atom/string/sse2-memchr-atom.S",
- "arch-x86/atom/string/sse2-memrchr-atom.S",
- "arch-x86/atom/string/sse2-strchr-atom.S",
- "arch-x86/atom/string/sse2-strnlen-atom.S",
- "arch-x86/atom/string/sse2-strrchr-atom.S",
- "arch-x86/atom/string/sse2-wcschr-atom.S",
- "arch-x86/atom/string/sse2-wcsrchr-atom.S",
- "arch-x86/atom/string/sse2-wcslen-atom.S",
- "arch-x86/atom/string/sse2-wcscmp-atom.S",
- "arch-x86/silvermont/string/sse2-memmove-slm.S",
- "arch-x86/silvermont/string/sse2-memset-slm.S",
- "arch-x86/silvermont/string/sse2-stpcpy-slm.S",
- "arch-x86/silvermont/string/sse2-stpncpy-slm.S",
- "arch-x86/silvermont/string/sse2-strcpy-slm.S",
- "arch-x86/silvermont/string/sse2-strlen-slm.S",
- "arch-x86/silvermont/string/sse2-strncpy-slm.S",
+ "arch-x86/string/sse2-memchr-atom.S",
+ "arch-x86/string/sse2-memmove-slm.S",
+ "arch-x86/string/sse2-memrchr-atom.S",
+ "arch-x86/string/sse2-memset-atom.S",
+ "arch-x86/string/sse2-memset-slm.S",
+ "arch-x86/string/sse2-stpcpy-slm.S",
+ "arch-x86/string/sse2-stpncpy-slm.S",
+ "arch-x86/string/sse2-strchr-atom.S",
+ "arch-x86/string/sse2-strcpy-slm.S",
+ "arch-x86/string/sse2-strlen-slm.S",
+ "arch-x86/string/sse2-strncpy-slm.S",
+ "arch-x86/string/sse2-strnlen-atom.S",
+ "arch-x86/string/sse2-strrchr-atom.S",
+ "arch-x86/string/sse2-wcschr-atom.S",
+ "arch-x86/string/sse2-wcsrchr-atom.S",
+ "arch-x86/string/sse2-wcslen-atom.S",
+ "arch-x86/string/sse2-wcscmp-atom.S",
+ "arch-x86/string/sse2-strlen-atom.S",
+
+ "arch-x86/string/ssse3-memcmp-atom.S",
+ "arch-x86/string/ssse3-memmove-atom.S",
+ "arch-x86/string/ssse3-strcat-atom.S",
+ "arch-x86/string/ssse3-strcmp-atom.S",
+ "arch-x86/string/ssse3-strcpy-atom.S",
+ "arch-x86/string/ssse3-strlcat-atom.S",
+ "arch-x86/string/ssse3-strlcpy-atom.S",
+ "arch-x86/string/ssse3-strncat-atom.S",
+ "arch-x86/string/ssse3-strncmp-atom.S",
+ "arch-x86/string/ssse3-strncpy-atom.S",
+ "arch-x86/string/ssse3-wcscat-atom.S",
+ "arch-x86/string/ssse3-wcscpy-atom.S",
+ "arch-x86/string/ssse3-wmemcmp-atom.S",
+
+ "arch-x86/string/sse4-memcmp-slm.S",
+ "arch-x86/string/sse4-wmemcmp-slm.S",
"arch-x86/bionic/__bionic_clone.S",
"arch-x86/bionic/_exit_with_stack_teardown.S",
@@ -950,32 +988,6 @@
"arch-x86/bionic/syscall.S",
"arch-x86/bionic/vfork.S",
"arch-x86/bionic/__x86.get_pc_thunk.S",
-
- // ssse3 functions
- "arch-x86/atom/string/ssse3-strcat-atom.S",
- "arch-x86/atom/string/ssse3-strcmp-atom.S",
- "arch-x86/atom/string/ssse3-strlcat-atom.S",
- "arch-x86/atom/string/ssse3-strlcpy-atom.S",
- "arch-x86/atom/string/ssse3-strncat-atom.S",
- "arch-x86/atom/string/ssse3-strncmp-atom.S",
- "arch-x86/atom/string/ssse3-wcscat-atom.S",
- "arch-x86/atom/string/ssse3-wcscpy-atom.S",
-
- // sse4 functions
- "arch-x86/silvermont/string/sse4-memcmp-slm.S",
- "arch-x86/silvermont/string/sse4-wmemcmp-slm.S",
-
- // atom functions
- "arch-x86/atom/string/sse2-memset-atom.S",
- "arch-x86/atom/string/sse2-strlen-atom.S",
- "arch-x86/atom/string/ssse3-memcmp-atom.S",
- "arch-x86/atom/string/ssse3-memmove-atom.S",
- "arch-x86/atom/string/ssse3-strcpy-atom.S",
- "arch-x86/atom/string/ssse3-strncpy-atom.S",
- "arch-x86/atom/string/ssse3-wmemcmp-atom.S",
-
- // avx2 functions
- "arch-x86/kabylake/string/avx2-wmemset-kbl.S",
],
exclude_srcs: [
@@ -986,6 +998,7 @@
},
x86_64: {
srcs: [
+ "arch-x86_64/string/avx2-memset-kbl.S",
"arch-x86_64/string/sse2-memmove-slm.S",
"arch-x86_64/string/sse2-memset-slm.S",
"arch-x86_64/string/sse2-stpcpy-slm.S",
@@ -998,7 +1011,6 @@
"arch-x86_64/string/sse4-memcmp-slm.S",
"arch-x86_64/string/ssse3-strcmp-slm.S",
"arch-x86_64/string/ssse3-strncmp-slm.S",
- "arch-x86_64/string/avx2-wmemset-kbl.S",
"arch-x86_64/bionic/__bionic_clone.S",
"arch-x86_64/bionic/_exit_with_stack_teardown.S",
@@ -1115,6 +1127,7 @@
"bionic/mbrtoc16.cpp",
"bionic/mbrtoc32.cpp",
"bionic/mempcpy.cpp",
+ "bionic/memset_explicit.cpp",
"bionic/mkdir.cpp",
"bionic/mkfifo.cpp",
"bionic/mknod.cpp",
@@ -1303,44 +1316,40 @@
name: "syscalls-arm.S",
out: ["syscalls-arm.S"],
srcs: ["SYSCALLS.TXT"],
- tool_files: [":bionic-gensyscalls"],
- cmd: "$(location :bionic-gensyscalls) arm $(in) > $(out)",
- bazel_module: {
- bp2build_available: true,
- }
+ tools: ["gensyscalls"],
+ cmd: "$(location gensyscalls) arm $(in) > $(out)",
}
genrule {
name: "syscalls-arm64.S",
out: ["syscalls-arm64.S"],
srcs: ["SYSCALLS.TXT"],
- tool_files: [":bionic-gensyscalls"],
- cmd: "$(location :bionic-gensyscalls) arm64 $(in) > $(out)",
- bazel_module: {
- bp2build_available: true,
- },
+ tools: ["gensyscalls"],
+ cmd: "$(location gensyscalls) arm64 $(in) > $(out)",
+}
+
+genrule {
+ name: "syscalls-riscv64.S",
+ out: ["syscalls-riscv64.S"],
+ srcs: ["SYSCALLS.TXT"],
+ tools: ["gensyscalls"],
+ cmd: "$(location gensyscalls) riscv64 $(in) > $(out)",
}
genrule {
name: "syscalls-x86.S",
out: ["syscalls-x86.S"],
srcs: ["SYSCALLS.TXT"],
- tool_files: [":bionic-gensyscalls"],
- cmd: "$(location :bionic-gensyscalls) x86 $(in) > $(out)",
- bazel_module: {
- bp2build_available: true,
- },
+ tools: ["gensyscalls"],
+ cmd: "$(location gensyscalls) x86 $(in) > $(out)",
}
genrule {
name: "syscalls-x86_64.S",
out: ["syscalls-x86_64.S"],
srcs: ["SYSCALLS.TXT"],
- tool_files: [":bionic-gensyscalls"],
- cmd: "$(location :bionic-gensyscalls) x86_64 $(in) > $(out)",
- bazel_module: {
- bp2build_available: true,
- },
+ tools: ["gensyscalls"],
+ cmd: "$(location gensyscalls) x86_64 $(in) > $(out)",
}
cc_library_static {
@@ -1353,6 +1362,9 @@
arm64: {
srcs: [":syscalls-arm64.S"],
},
+ riscv64: {
+ srcs: [":syscalls-riscv64.S"],
+ },
x86: {
srcs: [":syscalls-x86.S"],
},
@@ -1511,6 +1523,9 @@
name: "libc_static_dispatch",
arch: {
+ x86_64: {
+ srcs: ["arch-x86_64/static_function_dispatch.S"],
+ },
x86: {
srcs: ["arch-x86/static_function_dispatch.S"],
},
@@ -1536,6 +1551,9 @@
"-fno-jump-tables",
],
arch: {
+ x86_64: {
+ srcs: ["arch-x86_64/dynamic_function_dispatch.cpp"],
+ },
x86: {
srcs: ["arch-x86/dynamic_function_dispatch.cpp"],
},
@@ -1627,7 +1645,6 @@
"bionic/NetdClient.cpp",
"arch-common/bionic/crtend_so.S",
],
- bazel_module: { bp2build_available: true },
}
filegroup {
@@ -1638,7 +1655,6 @@
"bionic/malloc_common.cpp",
"bionic/malloc_limit.cpp",
],
- bazel_module: { bp2build_available: true },
}
filegroup {
@@ -1647,7 +1663,6 @@
"arch-arm/bionic/exidx_dynamic.c",
"arch-arm/bionic/atexit_legacy.c",
],
- bazel_module: { bp2build_available: true },
}
// ========================================================
@@ -1686,8 +1701,8 @@
},
required: [
- "tzdata",
- "tz_version", // Version metadata for tzdata to help debugging.
+ "tzdata_prebuilt",
+ "tz_version_prebuilt", // Version metadata for tzdata to help debugging.
],
// Do not pack libc.so relocations; see http://b/20645321 for details.
@@ -1745,6 +1760,15 @@
keep_symbols: true,
},
},
+ riscv64: {
+ version_script: ":libc.riscv64.map",
+
+ // Leave the symbols in the shared library so that stack unwinders can produce
+ // meaningful name resolution.
+ strip: {
+ keep_symbols: true,
+ },
+ },
x86: {
// TODO: This is to work around b/24465209. Remove after root cause is fixed.
pack_relocations: false,
@@ -1807,36 +1831,40 @@
name: "libc.arm.map",
out: ["libc.arm.map"],
srcs: ["libc.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) arm $(in) $(out)",
- bazel_module: { bp2build_available: true },
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) arm $(in) $(out)",
}
genrule {
name: "libc.arm64.map",
out: ["libc.arm64.map"],
srcs: ["libc.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) arm64 $(in) $(out)",
- bazel_module: { bp2build_available: true },
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) arm64 $(in) $(out)",
+}
+
+genrule {
+ name: "libc.riscv64.map",
+ out: ["libc.riscv64.map"],
+ srcs: ["libc.map.txt"],
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
}
genrule {
name: "libc.x86.map",
out: ["libc.x86.map"],
srcs: ["libc.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) x86 $(in) $(out)",
- bazel_module: { bp2build_available: true },
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) x86 $(in) $(out)",
}
genrule {
name: "libc.x86_64.map",
out: ["libc.x86_64.map"],
srcs: ["libc.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) x86_64 $(in) $(out)",
- bazel_module: { bp2build_available: true },
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
}
// Headers that only other parts of the platform can include.
@@ -1852,6 +1880,7 @@
"//external/perfetto:__subpackages__",
"//external/scudo:__subpackages__",
"//system/core/debuggerd:__subpackages__",
+ "//system/core/init:__subpackages__",
"//system/core/libcutils:__subpackages__",
"//system/memory/libmemunreachable:__subpackages__",
"//system/unwinding/libunwindstack:__subpackages__",
@@ -1875,7 +1904,6 @@
"//apex_available:platform",
"//apex_available:anyapex",
],
- bazel_module: { bp2build_available: true },
}
cc_library_headers {
@@ -1925,6 +1953,9 @@
arm64: {
export_system_include_dirs: ["kernel/uapi/asm-arm64"],
},
+ riscv64: {
+ export_system_include_dirs: ["kernel/uapi/asm-riscv"],
+ },
x86: {
export_system_include_dirs: ["kernel/uapi/asm-x86"],
},
@@ -1932,7 +1963,6 @@
export_system_include_dirs: ["kernel/uapi/asm-x86"],
},
},
- bazel_module: { bp2build_available: true },
}
cc_library_headers {
@@ -1980,7 +2010,6 @@
export_header_lib_headers: ["libc_llndk_headers"],
},
},
- bazel_module: { bp2build_available: true },
}
// ========================================================
@@ -2021,6 +2050,9 @@
arm64: {
version_script: ":libstdc++.arm64.map",
},
+ riscv64: {
+ version_script: ":libstdc++.riscv64.map",
+ },
x86: {
pack_relocations: false,
ldflags: ["-Wl,--hash-style=both"],
@@ -2036,32 +2068,40 @@
name: "libstdc++.arm.map",
out: ["libstdc++.arm.map"],
srcs: ["libstdc++.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) arm $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) arm $(in) $(out)",
}
genrule {
name: "libstdc++.arm64.map",
out: ["libstdc++.arm64.map"],
srcs: ["libstdc++.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) arm64 $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) arm64 $(in) $(out)",
+}
+
+genrule {
+ name: "libstdc++.riscv64.map",
+ out: ["libstdc++.riscv64.map"],
+ srcs: ["libstdc++.map.txt"],
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
}
genrule {
name: "libstdc++.x86.map",
out: ["libstdc++.x86.map"],
srcs: ["libstdc++.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) x86 $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) x86 $(in) $(out)",
}
genrule {
name: "libstdc++.x86_64.map",
out: ["libstdc++.x86_64.map"],
srcs: ["libstdc++.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) x86_64 $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
}
// ========================================================
@@ -2131,8 +2171,6 @@
srcs: ["arch-common/bionic/crtbrand.S"],
defaults: ["crt_so_defaults"],
-
- bazel_module: { bp2build_available: true },
}
cc_object {
@@ -2144,8 +2182,6 @@
objs: [
"crtbrand",
],
-
- bazel_module: { bp2build_available: true },
}
cc_object {
@@ -2157,8 +2193,6 @@
srcs: ["arch-common/bionic/crtend_so.S"],
defaults: ["crt_so_defaults"],
-
- bazel_module: { bp2build_available: true },
}
cc_object {
@@ -2176,8 +2210,6 @@
defaults: ["crt_defaults"],
// When using libc.a, we're using the latest library regardless of target API level.
min_sdk_version: "current",
-
- bazel_module: { bp2build_available: true },
}
cc_object {
@@ -2200,8 +2232,6 @@
},
},
defaults: ["crt_defaults"],
-
- bazel_module: { bp2build_available: true },
}
cc_object {
@@ -2215,8 +2245,6 @@
srcs: ["arch-common/bionic/crtend.S"],
defaults: ["crt_defaults"],
-
- bazel_module: { bp2build_available: true },
}
cc_library_static {
@@ -2306,6 +2334,14 @@
}
ndk_headers {
+ name: "libc_asm_riscv64",
+ from: "kernel/uapi/asm-riscv",
+ to: "riscv64-linux-android",
+ srcs: ["kernel/uapi/asm-riscv/**/*.h"],
+ license: "NOTICE",
+}
+
+ndk_headers {
name: "libc_asm_x86",
from: "kernel/uapi/asm-x86",
to: "i686-linux-android",
@@ -2327,6 +2363,17 @@
first_version: "9",
// APIs implemented in asm don't have debug info: http://b/190554910.
allow_untyped_symbols: true,
+ export_header_libs: [
+ "common_libc",
+ "libc_uapi",
+ "libc_kernel_android_uapi_linux",
+ "libc_kernel_android_scsi",
+ "libc_asm_arm",
+ "libc_asm_arm64",
+ "libc_asm_riscv64",
+ "libc_asm_x86",
+ "libc_asm_x86_64",
+ ],
}
ndk_library {
@@ -2342,7 +2389,6 @@
"kernel/uapi/linux/input.h",
"kernel/uapi/linux/input-event-codes.h",
],
- bazel_module: { bp2build_available: true },
}
// Generate a syscall name / number mapping. These objects are text files
@@ -2368,8 +2414,6 @@
"kernel/uapi/asm-arm",
"kernel/uapi",
],
-
- bazel_module: { bp2build_available: true },
}
cc_object {
@@ -2379,8 +2423,15 @@
"kernel/uapi/asm-arm64",
"kernel/uapi",
],
+}
- bazel_module: { bp2build_available: true },
+cc_object {
+ name: "libseccomp_gen_syscall_nrs_riscv64",
+ defaults: ["libseccomp_gen_syscall_nrs_defaults"],
+ local_include_dirs: [
+ "kernel/uapi/asm-riscv",
+ "kernel/uapi",
+ ],
}
cc_object {
@@ -2392,8 +2443,6 @@
"kernel/uapi/asm-x86",
"kernel/uapi",
],
-
- bazel_module: { bp2build_available: true },
}
cc_object {
@@ -2405,14 +2454,11 @@
"kernel/uapi/asm-x86",
"kernel/uapi",
],
-
- bazel_module: { bp2build_available: true },
}
filegroup {
name: "all_kernel_uapi_headers",
srcs: ["kernel/uapi/**/*.h"],
- bazel_module: { bp2build_available: true },
}
@@ -2425,12 +2471,38 @@
srcs: [
"SYSCALLS.TXT",
- ":libseccomp_gen_syscall_nrs_arm",
- ":libseccomp_gen_syscall_nrs_arm64",
- ":libseccomp_gen_syscall_nrs_x86",
- ":libseccomp_gen_syscall_nrs_x86_64",
],
+ arch: {
+ arm: {
+ srcs: [
+ ":libseccomp_gen_syscall_nrs_arm",
+ ":libseccomp_gen_syscall_nrs_arm64",
+ ],
+ },
+ arm64: {
+ srcs: [
+ ":libseccomp_gen_syscall_nrs_arm",
+ ":libseccomp_gen_syscall_nrs_arm64",
+ ],
+ },
+ riscv64: {
+ srcs: [":libseccomp_gen_syscall_nrs_riscv64"],
+ },
+ x86: {
+ srcs: [
+ ":libseccomp_gen_syscall_nrs_x86",
+ ":libseccomp_gen_syscall_nrs_x86_64",
+ ],
+ },
+ x86_64: {
+ srcs: [
+ ":libseccomp_gen_syscall_nrs_x86",
+ ":libseccomp_gen_syscall_nrs_x86_64",
+ ],
+ },
+ },
+
out: [
"func_to_syscall_nrs.h",
],
@@ -2444,13 +2516,8 @@
cmd: "grep -v '^int[ \t]*setresgid' $(in) > $(out)",
}
-cc_genrule {
- name: "libseccomp_policy_app_zygote_sources",
- recovery_available: true,
- cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=app_zygote $(in)",
-
- tools: [ "genseccomp" ],
-
+filegroup {
+ name: "seccomp_syscalls_sources_zygote",
srcs: [
"SYSCALLS.TXT",
"SECCOMP_ALLOWLIST_COMMON.TXT",
@@ -2458,27 +2525,11 @@
"SECCOMP_BLOCKLIST_COMMON.TXT",
"SECCOMP_PRIORITY.TXT",
":generate_app_zygote_blocklist",
- ":libseccomp_gen_syscall_nrs_arm",
- ":libseccomp_gen_syscall_nrs_arm64",
- ":libseccomp_gen_syscall_nrs_x86",
- ":libseccomp_gen_syscall_nrs_x86_64",
- ],
-
- out: [
- "arm64_app_zygote_policy.cpp",
- "arm_app_zygote_policy.cpp",
- "x86_64_app_zygote_policy.cpp",
- "x86_app_zygote_policy.cpp",
],
}
-cc_genrule {
- name: "libseccomp_policy_app_sources",
- recovery_available: true,
- cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=app $(in)",
-
- tools: [ "genseccomp" ],
-
+filegroup {
+ name: "seccomp_syscalls_sources_app",
srcs: [
"SYSCALLS.TXT",
"SECCOMP_ALLOWLIST_COMMON.TXT",
@@ -2486,56 +2537,242 @@
"SECCOMP_BLOCKLIST_COMMON.TXT",
"SECCOMP_BLOCKLIST_APP.TXT",
"SECCOMP_PRIORITY.TXT",
- ":libseccomp_gen_syscall_nrs_arm",
- ":libseccomp_gen_syscall_nrs_arm64",
- ":libseccomp_gen_syscall_nrs_x86",
- ":libseccomp_gen_syscall_nrs_x86_64",
- ],
-
- out: [
- "arm64_app_policy.cpp",
- "arm_app_policy.cpp",
- "x86_64_app_policy.cpp",
- "x86_app_policy.cpp",
],
}
-cc_genrule {
- name: "libseccomp_policy_system_sources",
- recovery_available: true,
- cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=system $(in)",
-
- tools: [ "genseccomp" ],
-
+filegroup {
+ name: "seccomp_syscalls_sources_system",
srcs: [
"SYSCALLS.TXT",
"SECCOMP_ALLOWLIST_COMMON.TXT",
"SECCOMP_ALLOWLIST_SYSTEM.TXT",
"SECCOMP_BLOCKLIST_COMMON.TXT",
"SECCOMP_PRIORITY.TXT",
- ":libseccomp_gen_syscall_nrs_arm",
- ":libseccomp_gen_syscall_nrs_arm64",
+ ],
+}
+
+cc_genrule {
+ name: "libseccomp_policy_app_zygote_sources_x86",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=app_zygote $(in)",
+ tools: [ "genseccomp" ],
+ srcs: [
+ ":seccomp_syscalls_sources_zygote",
":libseccomp_gen_syscall_nrs_x86",
":libseccomp_gen_syscall_nrs_x86_64",
],
-
out: [
- "arm64_system_policy.cpp",
- "arm_system_policy.cpp",
- "x86_64_system_policy.cpp",
- "x86_system_policy.cpp",
+ "x86_app_zygote_policy.cpp",
+ "x86_64_app_zygote_policy.cpp",
],
+ enabled: false,
+ arch: {
+ x86: { enabled: true },
+ x86_64: { enabled: true },
+ },
+}
+
+cc_genrule {
+ name: "libseccomp_policy_app_zygote_sources_arm",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=app_zygote $(in)",
+ tools: [ "genseccomp" ],
+ srcs: [
+ ":seccomp_syscalls_sources_zygote",
+ ":libseccomp_gen_syscall_nrs_arm",
+ ":libseccomp_gen_syscall_nrs_arm64",
+ ],
+ out: [
+ "arm_app_zygote_policy.cpp",
+ "arm64_app_zygote_policy.cpp",
+ ],
+ enabled: false,
+ arch: {
+ arm: { enabled: true },
+ arm64: { enabled: true },
+ },
+}
+
+cc_genrule {
+ name: "libseccomp_policy_app_zygote_sources_riscv64",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=app_zygote $(in)",
+ tools: [ "genseccomp" ],
+ srcs: [
+ ":seccomp_syscalls_sources_zygote",
+ ":libseccomp_gen_syscall_nrs_riscv64",
+ ],
+ out: [
+ "riscv64_app_zygote_policy.cpp",
+ ],
+ enabled: false,
+ arch: {
+ riscv64: { enabled: true },
+ },
+}
+
+cc_genrule {
+ name: "libseccomp_policy_app_sources_x86",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=app $(in)",
+ tools: [ "genseccomp" ],
+ srcs: [
+ ":seccomp_syscalls_sources_app",
+ ":libseccomp_gen_syscall_nrs_x86",
+ ":libseccomp_gen_syscall_nrs_x86_64",
+ ],
+ out: [
+ "x86_app_policy.cpp",
+ "x86_64_app_policy.cpp",
+ ],
+ enabled: false,
+ arch: {
+ x86: { enabled: true },
+ x86_64: { enabled: true },
+ },
+}
+
+cc_genrule {
+ name: "libseccomp_policy_app_sources_arm",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=app $(in)",
+ tools: [ "genseccomp" ],
+ srcs: [
+ ":seccomp_syscalls_sources_app",
+ ":libseccomp_gen_syscall_nrs_arm",
+ ":libseccomp_gen_syscall_nrs_arm64",
+ ],
+ out: [
+ "arm_app_policy.cpp",
+ "arm64_app_policy.cpp",
+ ],
+ enabled: false,
+ arch: {
+ arm: { enabled: true },
+ arm64: { enabled: true },
+ },
+}
+
+cc_genrule {
+ name: "libseccomp_policy_app_sources_riscv64",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=app $(in)",
+ tools: [ "genseccomp" ],
+ srcs: [
+ ":seccomp_syscalls_sources_app",
+ ":libseccomp_gen_syscall_nrs_riscv64",
+ ],
+ out: [
+ "riscv64_app_policy.cpp",
+ ],
+ enabled: false,
+ arch: {
+ riscv64: { enabled: true },
+ },
+}
+
+cc_genrule {
+ name: "libseccomp_policy_system_sources_x86",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=system $(in)",
+ tools: [ "genseccomp" ],
+ srcs: [
+ ":seccomp_syscalls_sources_system",
+ ":libseccomp_gen_syscall_nrs_x86",
+ ":libseccomp_gen_syscall_nrs_x86_64",
+ ],
+ out: [
+ "x86_system_policy.cpp",
+ "x86_64_system_policy.cpp",
+ ],
+ enabled: false,
+ arch: {
+ x86: { enabled: true },
+ x86_64: { enabled: true },
+ },
+}
+
+cc_genrule {
+ name: "libseccomp_policy_system_sources_arm",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=system $(in)",
+ tools: [ "genseccomp" ],
+ srcs: [
+ ":seccomp_syscalls_sources_system",
+ ":libseccomp_gen_syscall_nrs_arm",
+ ":libseccomp_gen_syscall_nrs_arm64",
+ ],
+ out: [
+ "arm_system_policy.cpp",
+ "arm64_system_policy.cpp",
+ ],
+ enabled: false,
+ arch: {
+ arm: { enabled: true },
+ arm64: { enabled: true },
+ },
+}
+
+cc_genrule {
+ name: "libseccomp_policy_system_sources_riscv64",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=system $(in)",
+ tools: [ "genseccomp" ],
+ srcs: [
+ ":seccomp_syscalls_sources_system",
+ ":libseccomp_gen_syscall_nrs_riscv64",
+ ],
+ out: [
+ "riscv64_system_policy.cpp",
+ ],
+ enabled: false,
+ arch: {
+ riscv64: { enabled: true },
+ },
}
cc_library {
name: "libseccomp_policy",
recovery_available: true,
generated_headers: ["func_to_syscall_nrs"],
- generated_sources: [
- "libseccomp_policy_app_sources",
- "libseccomp_policy_app_zygote_sources",
- "libseccomp_policy_system_sources",
- ],
+
+ arch: {
+ arm: {
+ generated_sources: [
+ "libseccomp_policy_app_sources_arm",
+ "libseccomp_policy_app_zygote_sources_arm",
+ "libseccomp_policy_system_sources_arm",
+ ],
+ },
+ arm64: {
+ generated_sources: [
+ "libseccomp_policy_app_sources_arm",
+ "libseccomp_policy_app_zygote_sources_arm",
+ "libseccomp_policy_system_sources_arm",
+ ],
+ },
+ riscv64: {
+ generated_sources: [
+ "libseccomp_policy_app_sources_riscv64",
+ "libseccomp_policy_app_zygote_sources_riscv64",
+ "libseccomp_policy_system_sources_riscv64",
+ ],
+ },
+ x86: {
+ generated_sources: [
+ "libseccomp_policy_app_sources_x86",
+ "libseccomp_policy_app_zygote_sources_x86",
+ "libseccomp_policy_system_sources_x86",
+ ],
+ },
+ x86_64: {
+ generated_sources: [
+ "libseccomp_policy_app_sources_x86",
+ "libseccomp_policy_app_zygote_sources_x86",
+ "libseccomp_policy_system_sources_x86",
+ ],
+ },
+ },
srcs: [
"seccomp/seccomp_policy.cpp",
@@ -2666,6 +2903,7 @@
" -D $${BIONIC_LIBC_DIR}/b64/include " +
" && " +
"$(location zip2zip) -i $(genDir)/sysroot.zip -o $(genDir)/sysroot-renamed.zip " +
+ " -x **/BUILD " +
" include/**/*:include/ " +
" NOTICE:NOTICE.bionic " +
" && " +
@@ -2705,3 +2943,53 @@
tools: ["soong_zip"],
cmd: "includes=($(in)) && $(location soong_zip) -o $(out) -P include/asm -j -D $$(dirname $${includes[0]})",
}
+
+cc_genrule {
+ name: "bionic_sysroot_crt_objects",
+ visibility: ["//visibility:private"],
+ out: ["bionic_sysroot_crt_objects.zip"],
+ tools: ["soong_zip"],
+ srcs: [
+ ":crtbegin_dynamic",
+ ":crtbegin_so",
+ ":crtbegin_static",
+ ":crtend_android",
+ ":crtend_so",
+ ],
+ cmd: "$(location soong_zip) -o $(out) -j " +
+ "-f $(location :crtbegin_dynamic) " +
+ "-f $(location :crtbegin_so) " +
+ "-f $(location :crtbegin_static) " +
+ "-f $(location :crtend_android) " +
+ "-f $(location :crtend_so)",
+ dist: {
+ targets: ["bionic_sysroot_crt_objects"],
+ },
+ arch: {
+ arm: {
+ dist: {
+ suffix: "_arm",
+ },
+ },
+ arm64: {
+ dist: {
+ suffix: "_arm64",
+ },
+ },
+ riscv64: {
+ dist: {
+ suffix: "_riscv64",
+ },
+ },
+ x86: {
+ dist: {
+ suffix: "_x86",
+ },
+ },
+ x86_64: {
+ dist: {
+ suffix: "_x86_64",
+ },
+ },
+ },
+}
diff --git a/libc/BUILD b/libc/BUILD
new file mode 100644
index 0000000..1777ae9
--- /dev/null
+++ b/libc/BUILD
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Android Open Source Project
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+load("//build/bazel/rules/apis:cc_api_contribution.bzl", "cc_api_contribution")
+
+cc_api_contribution(
+ name = "libc_contributions",
+ hdrs = [
+ "//bionic/libc/kernel/android:libc_kernel_android_scsi_headers",
+ "//bionic/libc/kernel/android:libc_kernel_android_uapi_headers",
+ "//bionic/libc/kernel/uapi:libc_kernel_uapi_asm_arm64_headers", #arm64
+ "//bionic/libc/kernel/uapi:libc_kernel_uapi_asm_arm_headers", #arm
+ "//bionic/libc/kernel/uapi:libc_kernel_uapi_asm_x86_64_headers", #x86_64
+ "//bionic/libc/kernel/uapi:libc_kernel_uapi_asm_x86_headers", #x86
+ "//bionic/libc/kernel/uapi:libc_kernel_uapi_headers",
+ ],
+ api = ":libc.map.txt",
+ library_name = "libc",
+)
diff --git a/libc/NOTICE b/libc/NOTICE
index 9cbbde2..51f43f1 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -783,22 +783,6 @@
-------------------------------------------------------------------
Copyright (C) 2019 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--------------------------------------------------------------------
-
-Copyright (C) 2019 The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -826,34 +810,6 @@
-------------------------------------------------------------------
-Copyright (C) 2019 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
Copyright (C) 2020 The Android Open Source Project
All rights reserved.
@@ -2096,6 +2052,38 @@
Copyright (c) 1990, 1993
The Regents of the University of California. All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Mike Hibler and Chris Torek.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1990, 1993
+ The Regents of the University of California. All rights reserved.
(c) UNIX System Laboratories, Inc.
All or some portions of this file are derived from material licensed
to the University of California by American Telephone and Telegraph
@@ -4605,6 +4593,34 @@
-------------------------------------------------------------------
+Copyright (c) 2017, 2018 Dell EMC
+Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien
+Copyright (c) 1998 John D. Polstra.
+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)1999 Citrus Project,
All rights reserved.
diff --git a/libc/SECCOMP_ALLOWLIST_APP.TXT b/libc/SECCOMP_ALLOWLIST_APP.TXT
index ba40b60..7e1ecde 100644
--- a/libc/SECCOMP_ALLOWLIST_APP.TXT
+++ b/libc/SECCOMP_ALLOWLIST_APP.TXT
@@ -56,3 +56,7 @@
# b/62090571
int mkdir(const char *pathname, mode_t mode) lp32
+
+# Not used by bionic in U because riscv64 doesn't have it, but still
+# used by legacy apps (http://b/254179267).
+int renameat(int, const char*, int, const char*) arm,x86,arm64,x86_64
diff --git a/libc/SECCOMP_ALLOWLIST_COMMON.TXT b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
index 0366fdf..a4218ee 100644
--- a/libc/SECCOMP_ALLOWLIST_COMMON.TXT
+++ b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
@@ -76,5 +76,3 @@
int sched_rr_get_interval_time64(pid_t, timespec64*) lp32
# Since Linux 5.4, not in glibc. Probed for and conditionally used by ART.
int userfaultfd(int) all
-# Since Linux 5.9, used by POSIX_SPAWN_CLOEXEC_DEFAULT
-int close_range(unsigned int, unsigned int, int) all
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index a09c614..1b9054b 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -7,7 +7,7 @@
# where:
# arch_list ::= "all" | arches
# arches ::= arch | arch "," arches
-# arch ::= "arm" | "arm64" | "x86" | "x86_64" | "lp32" | "lp64"
+# arch ::= "arm" | "arm64" | "riscv64" | "x86" | "x86_64" | "lp32" | "lp64"
#
# Note:
# - syscall_name corresponds to the name of the syscall, which may differ from
@@ -26,7 +26,7 @@
# This file is processed by a python script named gensyscalls.py, run via
# genrules in Android.bp.
-int execve(const char*, char* const*, char* const*) all
+int __execve:execve(const char*, char* const*, char* const*) all
uid_t getuid:getuid32() lp32
uid_t getuid:getuid() lp64
@@ -107,6 +107,8 @@
ssize_t __pwritev64v2:pwritev2(int, const struct iovec*, int, long, long, int) all
int __close:close(int) all
+int close_range(unsigned int, unsigned int, int) all
+ssize_t copy_file_range(int, off64_t*, int, off64_t*, size_t, unsigned int) all
pid_t __getpid:getpid() all
int memfd_create(const char*, unsigned) all
int munmap(void*, size_t) all
@@ -154,7 +156,6 @@
int mkdirat(int, const char*, mode_t) all
int mknodat(int, const char*, mode_t, dev_t) all
int readlinkat(int, const char*, char*, size_t) all
-int renameat(int, const char*, int, const char*) all
int renameat2(int, const char*, int, const char*, unsigned) all
int symlinkat(const char*, int, const char*) all
int unlinkat(int, const char*, int) all
@@ -318,7 +319,7 @@
int __eventfd:eventfd2(unsigned int, int) all
-void _exit|_Exit:exit_group(int) all
+void __exit_group:exit_group(int) all
void __exit:exit(int) all
int inotify_init1(int) all
@@ -351,6 +352,9 @@
int __set_tls:__ARM_NR_set_tls(void*) arm
int cacheflush:__ARM_NR_cacheflush(long start, long end, long flags) arm
+# riscv64-specific
+int _flush_icache:riscv_flush_icache(void*, void*, unsigned long) riscv64
+
# x86-specific
int __set_thread_area:set_thread_area(void*) x86
diff --git a/libc/arch-arm64/bionic/setjmp.S b/libc/arch-arm64/bionic/setjmp.S
index d2fafdb..8e00b56 100644
--- a/libc/arch-arm64/bionic/setjmp.S
+++ b/libc/arch-arm64/bionic/setjmp.S
@@ -194,7 +194,7 @@
cmp x2, x12
bne __bionic_setjmp_checksum_mismatch
-#if __has_feature(hwaddress_sanitizer)
+ // Update stack memory tags (MTE + hwasan).
stp x0, x30, [sp, #-16]!
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x0, 0
@@ -206,7 +206,7 @@
bic x2, x2, #1
ldr x0, [x0, #(_JB_X30_SP * 8 + 8)]
eor x0, x0, x2
- bl __hwasan_handle_longjmp
+ bl memtag_handle_longjmp
mov x1, x19 // Restore 'value'.
// Restore original x0 and lr.
@@ -214,7 +214,6 @@
.cfi_adjust_cfa_offset -16
.cfi_restore x0
.cfi_restore x30
-#endif
// Do we need to restore the signal mask?
ldr x2, [x0, #(_JB_SIGFLAG * 8)]
diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S
index df7b063..9eb82d8 100644
--- a/libc/arch-arm64/bionic/vfork.S
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -29,10 +29,7 @@
#include <platform/bionic/tls_defines.h>
#include <private/bionic_asm.h>
#include <asm/signal.h>
-
-// Must match the defines in linux/sched.h
-#define CLONE_VM 0x00000100
-#define CLONE_VFORK 0x00004000
+#include <linux/sched.h>
ENTRY(vfork)
__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
@@ -45,6 +42,9 @@
ldr w10, [x9, #20]
str w0, [x9, #20]
+ // Clear vfork_child_stack_bottom_.
+ str xzr, [x9, #776]
+
mov x0, #(CLONE_VM | CLONE_VFORK | SIGCHLD)
mov x1, xzr
mov x2, xzr
@@ -62,9 +62,6 @@
cneg x0, x0, hi
b.hi __set_errno_internal
-#if __has_feature(hwaddress_sanitizer)
- cbz x0, .L_exit
-
// Clean up stack shadow in the parent process.
// https://github.com/google/sanitizers/issues/925
paciasp
@@ -75,7 +72,7 @@
.cfi_rel_offset x30, 8
add x0, sp, #16
- bl __hwasan_handle_vfork
+ bl memtag_handle_vfork
ldp x0, x30, [sp], #16
.cfi_adjust_cfa_offset -16
@@ -84,8 +81,6 @@
autiasp
.cfi_negate_ra_state
-#endif
-
.L_exit:
ret
END(vfork)
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index 9b8ad4e..b87db64 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -56,6 +56,8 @@
__asm__(PRE
"xorl %ebp,%ebp; movl %esp,%eax; andl $~0xf,%esp; subl $12,%esp; pushl %eax;"
"call _start_main" POST);
+#elif defined(__riscv)
+__asm__(PRE "li fp,0; li ra,0; mv a0,sp; tail _start_main" POST);
#elif defined(__x86_64__)
__asm__(PRE "xorl %ebp, %ebp; movq %rsp,%rdi; andq $~0xf,%rsp; callq _start_main" POST);
#else
diff --git a/libc/arch-riscv64/bionic/__bionic_clone.S b/libc/arch-riscv64/bionic/__bionic_clone.S
new file mode 100644
index 0000000..d535095
--- /dev/null
+++ b/libc/arch-riscv64/bionic/__bionic_clone.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+
+// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
+
+ENTRY_PRIVATE(__bionic_clone)
+ # Push 'fn' and 'arg' onto the child stack.
+ addi a1, a1, -16
+ sd a5, 0(a1)
+ sd a6, 8(a1)
+
+ # Make the system call.
+ li a7, __NR_clone
+ ecall
+
+ # Are we the child?
+ beqz a0, .L_bc_child
+
+ # Did the clone(2) fail?
+ bltz a0, .L_bc_failure
+ # Nope, we're the parent, and our work here is done.
+ ret
+
+.L_bc_failure:
+ # Set errno if something went wrong.
+ neg a0, a0
+ j __set_errno_internal
+
+.L_bc_child:
+ # We're in the child now. Set the end of the frame record chain.
+ li fp, 0
+ # Setting ra to 0 will make the unwinder stop at __start_thread.
+ li ra, 0
+ # Call __start_thread with the 'fn' and 'arg' we stored on the child stack.
+ ld a0, 0(sp)
+ ld a1, 8(sp)
+ addi sp, sp, 16
+ j __start_thread
+END(__bionic_clone)
diff --git a/libc/arch-riscv64/bionic/__set_tls.c b/libc/arch-riscv64/bionic/__set_tls.c
new file mode 100644
index 0000000..57383ab
--- /dev/null
+++ b/libc/arch-riscv64/bionic/__set_tls.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__LIBC_HIDDEN__ void __set_tls(void* tls) {
+ asm("mv tp, %0" : : "r"(tls));
+}
diff --git a/libc/arch-riscv64/bionic/_exit_with_stack_teardown.S b/libc/arch-riscv64/bionic/_exit_with_stack_teardown.S
new file mode 100644
index 0000000..f7bf58b
--- /dev/null
+++ b/libc/arch-riscv64/bionic/_exit_with_stack_teardown.S
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+
+// void _exit_with_stack_teardown(void* stackBase, size_t stackSize)
+ENTRY_PRIVATE(_exit_with_stack_teardown)
+ li a7, __NR_munmap
+ ecall
+ // If munmap failed, we ignore the failure and exit anyway.
+
+ li a0, 0
+ li a7, __NR_exit
+ ecall
+ // The exit syscall does not return.
+END(_exit_with_stack_teardown)
diff --git a/libc/arch-riscv64/bionic/setjmp.S b/libc/arch-riscv64/bionic/setjmp.S
new file mode 100644
index 0000000..eea2978
--- /dev/null
+++ b/libc/arch-riscv64/bionic/setjmp.S
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+#include <private/bionic_constants.h>
+
+// The internal structure of a jmp_buf is totally private.
+// Current layout (changes from release to release):
+//
+// word name description
+// 0 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit
+// 1 sigmask 64-bit signal mask
+// 2 ra
+// 3 s0
+// ......
+// 14 s11
+// 15 sp
+// 16 fs0
+// ......
+// 27 fs11
+// 28 checksum
+// _JBLEN: defined in bionic/libc/include/setjmp.h
+
+#define _JB_SIGFLAG 0
+#define _JB_SIGMASK 1 * 8
+#define _JB_RA 2 * 8
+#define _JB_S0 3 * 8
+#define _JB_S1 4 * 8
+#define _JB_S2 5 * 8
+#define _JB_S3 6 * 8
+#define _JB_S4 7 * 8
+#define _JB_S5 8 * 8
+#define _JB_S6 9 * 8
+#define _JB_S7 10 * 8
+#define _JB_S8 11 * 8
+#define _JB_S9 12 * 8
+#define _JB_S10 13 * 8
+#define _JB_S11 14 * 8
+#define _JB_SP 15 * 8
+#define _JB_FS0 16 * 8
+#define _JB_FS1 17 * 8
+#define _JB_FS2 18 * 8
+#define _JB_FS3 19 * 8
+#define _JB_FS4 20 * 8
+#define _JB_FS5 21 * 8
+#define _JB_FS6 22 * 8
+#define _JB_FS7 23 * 8
+#define _JB_FS8 24 * 8
+#define _JB_FS9 25 * 8
+#define _JB_FS10 26 * 8
+#define _JB_FS11 27 * 8
+#define _JB_CHECKSUM 28 * 8
+
+.macro m_mangle_registers reg, sp_reg
+ xor s0, s0, \reg
+ xor s1, s1, \reg
+ xor s2, s2, \reg
+ xor s3, s3, \reg
+ xor s4, s4, \reg
+ xor s5, s5, \reg
+ xor s6, s6, \reg
+ xor s7, s7, \reg
+ xor s8, s8, \reg
+ xor s9, s9, \reg
+ xor s10, s10, \reg
+ xor s11, s11, \reg
+ xor \sp_reg, \sp_reg, \reg
+.endm
+
+.macro m_calculate_checksum dst, src, scratch
+ li \dst, 0
+ .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27
+ ld \scratch, (\i * 8)(\src)
+ xor \dst, \dst, \scratch
+ .endr
+.endm
+
+.macro m_unmangle_registers reg, sp_reg
+ m_mangle_registers \reg, sp_reg=\sp_reg
+.endm
+
+ENTRY(setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(setjmp)
+ li a1, 1
+ tail sigsetjmp
+END(setjmp)
+
+ENTRY(_setjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_setjmp)
+ li a1, 0
+ tail sigsetjmp
+END(_setjmp)
+
+// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
+ENTRY(sigsetjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(sigsetjmp)
+ addi sp, sp, -24
+ sd a0, 0(sp)
+ sd a1, 8(sp)
+ sd ra, 16(sp)
+
+ // Get the cookie and store it along with the signal flag.
+ mv a0, a1
+ call __bionic_setjmp_cookie_get
+ mv a1, a0
+ ld a0, 0(sp)
+ sd a1, _JB_SIGFLAG(a0)
+
+ // Do we need to save the signal mask?
+ andi a1, a1, 1
+ beqz a1, 1f
+
+ // Save current signal mask.
+ // The 'how'/a0 argument is ignored if set is NULL.
+ li a1, 0 // NULL
+ addi a2, a0, _JB_SIGMASK // old_mask.
+ call sigprocmask
+
+1:
+ // Restore original a0/ra.
+ ld a0, 0(sp)
+ ld ra, 16(sp)
+ addi sp, sp, 24
+
+ // Get the cookie.
+ ld a1, _JB_SIGFLAG(a0)
+ andi a1, a1, -2
+
+ // Save core registers.
+ mv a2, sp
+ m_mangle_registers a1, sp_reg=a2
+ sd ra, _JB_RA(a0)
+ sd s0, _JB_S0(a0)
+ sd s1, _JB_S1(a0)
+ sd s2, _JB_S2(a0)
+ sd s3, _JB_S3(a0)
+ sd s4, _JB_S4(a0)
+ sd s5, _JB_S5(a0)
+ sd s6, _JB_S6(a0)
+ sd s7, _JB_S7(a0)
+ sd s8, _JB_S8(a0)
+ sd s9, _JB_S9(a0)
+ sd s10, _JB_S10(a0)
+ sd s11, _JB_S11(a0)
+ sd a2, _JB_SP(a0)
+ m_unmangle_registers a1, sp_reg=a2
+
+ // Save floating point registers.
+ fsd fs0, _JB_FS0(a0)
+ fsd fs1, _JB_FS1(a0)
+ fsd fs2, _JB_FS2(a0)
+ fsd fs3, _JB_FS3(a0)
+ fsd fs4, _JB_FS4(a0)
+ fsd fs5, _JB_FS5(a0)
+ fsd fs6, _JB_FS6(a0)
+ fsd fs7, _JB_FS7(a0)
+ fsd fs8, _JB_FS8(a0)
+ fsd fs9, _JB_FS9(a0)
+ fsd fs10, _JB_FS10(a0)
+ fsd fs11, _JB_FS11(a0)
+
+ // Calculate the checksum and save it.
+ m_calculate_checksum t0, a0, t1
+ sd t0, _JB_CHECKSUM(a0)
+
+ li a0, 0
+ ret
+END(sigsetjmp)
+
+// void siglongjmp(sigjmp_buf env, int value);
+ENTRY(siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(siglongjmp)
+ // Check the checksum before doing anything.
+ m_calculate_checksum t0, a0, t1
+ ld t1, _JB_CHECKSUM(a0)
+ bne t0, t1, 3f
+
+ // Do we need to restore the signal mask?
+ ld a2, _JB_SIGFLAG(a0)
+ andi a3, a2, 1
+ beqz a3, 1f
+
+ addi sp, sp, -16
+ sd a0, 0(sp)
+ sd ra, 8(sp)
+
+ // Restore the signal mask.
+ mv t0, a1 // Save 'value'.
+
+ mv a2, a0
+ li a0, 2 // SIG_SETMASK
+ addi a1, a2, _JB_SIGMASK // new_mask
+ li a2, 0 // NULL
+ call sigprocmask
+ mv a1, t0 // Restore 'value'.
+
+ // Restore original a0 and ra.
+ ld a0, 0(sp)
+ ld ra, 8(sp)
+ addi sp, sp, 16
+
+ ld a2, _JB_SIGFLAG(a0)
+1:
+ // Restore core registers.
+ andi a2, a2, -2
+ ld ra, _JB_RA(a0)
+ ld s0, _JB_S0(a0)
+ ld s1, _JB_S1(a0)
+ ld s2, _JB_S2(a0)
+ ld s3, _JB_S3(a0)
+ ld s4, _JB_S4(a0)
+ ld s5, _JB_S5(a0)
+ ld s6, _JB_S6(a0)
+ ld s7, _JB_S7(a0)
+ ld s8, _JB_S8(a0)
+ ld s9, _JB_S9(a0)
+ ld s10, _JB_S10(a0)
+ ld s11, _JB_S11(a0)
+ ld a3, _JB_SP(a0)
+ m_unmangle_registers a2, sp_reg=a3
+ mv sp, a3
+
+ addi sp, sp, -24
+ sd ra, 0(sp)
+ sd a0, 8(sp)
+ sd a1, 16(sp)
+ ld a0, _JB_SIGFLAG(a0)
+ call __bionic_setjmp_cookie_check
+ ld ra, 0(sp)
+ ld a0, 8(sp)
+ ld a1, 16(sp)
+ addi sp, sp, 24
+
+ // Restore floating point registers.
+ fld fs0, _JB_FS0(a0)
+ fld fs1, _JB_FS1(a0)
+ fld fs2, _JB_FS2(a0)
+ fld fs3, _JB_FS3(a0)
+ fld fs4, _JB_FS4(a0)
+ fld fs5, _JB_FS5(a0)
+ fld fs6, _JB_FS6(a0)
+ fld fs7, _JB_FS7(a0)
+ fld fs8, _JB_FS8(a0)
+ fld fs9, _JB_FS9(a0)
+ fld fs10, _JB_FS10(a0)
+ fld fs11, _JB_FS11(a0)
+
+ // Set return value.
+ beqz a1, 2f
+ li a0, 1
+2:
+ mv a0, a1
+ ret
+
+3:
+ call __bionic_setjmp_checksum_mismatch
+END(siglongjmp)
+
+ALIAS_SYMBOL(longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(longjmp)
+ALIAS_SYMBOL(_longjmp, siglongjmp)
+__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_longjmp)
diff --git a/libc/arch-riscv64/bionic/syscall.S b/libc/arch-riscv64/bionic/syscall.S
new file mode 100644
index 0000000..7b9d3ca
--- /dev/null
+++ b/libc/arch-riscv64/bionic/syscall.S
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+
+ENTRY(syscall)
+ // Move the syscall number up.
+ mv a7, a0
+
+ // Shuffle the arguments down.
+ mv a0, a1
+ mv a1, a2
+ mv a2, a3
+ mv a3, a4
+ mv a4, a5
+ mv a5, a6
+
+ ecall
+
+ // Did it fail?
+ li a7, -MAX_ERRNO
+ bgtu a0, a7, 1f
+
+ ret
+1:
+ neg a0, a0
+ j __set_errno_internal
+END(syscall)
diff --git a/libc/arch-riscv64/bionic/vfork.S b/libc/arch-riscv64/bionic/vfork.S
new file mode 100644
index 0000000..0eff9e9
--- /dev/null
+++ b/libc/arch-riscv64/bionic/vfork.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 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 <platform/bionic/tls_defines.h>
+#include <private/bionic_asm.h>
+#include <asm/signal.h>
+#include <linux/sched.h>
+
+ENTRY(vfork)
+ // t0 = __get_tls()[TLS_SLOT_THREAD_ID]
+ mv t0, tp
+ ld t0, TLS_SLOT_THREAD_ID * 8(t0)
+
+ // Set cached_pid_ to 0, vforked_ to 1, and stash the previous value.
+ li t1, 0x80000000
+ lw t2, 20(t0)
+ sw t1, 20(t0)
+
+ li a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
+ li a1, 0 //uses a duplicate of the parent's stack
+ li a2, 0
+ li a3, 0
+ li a4, 0
+
+ li a7, __NR_clone
+ ecall
+
+ // if (rc == 0) we're the child, and finished...
+ beqz a0, .L_success
+
+ // else if (rc != 0): reset cached_pid_ and vforked_...
+ sw t2, 20(t0)
+ // ...and work out whether we succeeded or failed.
+ bltz a0, .L_failure
+.L_success:
+ ret
+
+.L_failure:
+ neg a0, a0
+ j __set_errno_internal
+END(vfork)
diff --git a/libc/arch-riscv64/string/memset_chk.c b/libc/arch-riscv64/string/memset_chk.c
new file mode 100644
index 0000000..bdd15a5
--- /dev/null
+++ b/libc/arch-riscv64/string/memset_chk.c
@@ -0,0 +1,9 @@
+#include <stdint.h>
+
+extern void* memset(void*, int, size_t);
+extern void* __memset_chk_fail(void*, int, size_t, size_t);
+
+void* __memset_chk(void* dst, int c, size_t n, size_t dst_len) {
+ if (dst_len < n) __memset_chk_fail(dst, c, n, dst_len);
+ return memset(dst, c, n);
+}
diff --git a/libc/arch-x86/atom/string/cache.h b/libc/arch-x86/atom/string/cache.h
deleted file mode 100644
index 823bb1e..0000000
--- a/libc/arch-x86/atom/string/cache.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-Copyright (c) 2010, Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * Neither the name of Intel Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* Values are optimized for Atom */
-#define SHARED_CACHE_SIZE (512*1024) /* Atom L2 Cache */
-#define DATA_CACHE_SIZE (24*1024) /* Atom L1 Data Cache */
-
-#define SHARED_CACHE_SIZE_HALF (SHARED_CACHE_SIZE / 2)
-#define DATA_CACHE_SIZE_HALF (DATA_CACHE_SIZE / 2)
diff --git a/libc/arch-x86/dynamic_function_dispatch.cpp b/libc/arch-x86/dynamic_function_dispatch.cpp
index e94fa1f..38d8a0a 100644
--- a/libc/arch-x86/dynamic_function_dispatch.cpp
+++ b/libc/arch-x86/dynamic_function_dispatch.cpp
@@ -95,13 +95,6 @@
RETURN_FUNC(wmemcmp_func, wmemcmp_freebsd);
}
-typedef int wmemset_func(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
-DEFINE_IFUNC_FOR(wmemset) {
- __builtin_cpu_init();
- if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wmemset_func, wmemset_avx2);
- RETURN_FUNC(wmemset_func, wmemset_freebsd);
-}
-
typedef int strcmp_func(const char* __lhs, const char* __rhs);
DEFINE_IFUNC_FOR(strcmp) {
__builtin_cpu_init();
diff --git a/libc/arch-x86/generic/string/wmemset.c b/libc/arch-x86/generic/string/wmemset.c
deleted file mode 100644
index 35d489f..0000000
--- a/libc/arch-x86/generic/string/wmemset.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-#define wmemset wmemset_freebsd
-
-#include <upstream-freebsd/lib/libc/string/wmemset.c>
diff --git a/libc/arch-x86/kabylake/string/avx2-wmemset-kbl.S b/libc/arch-x86/kabylake/string/avx2-wmemset-kbl.S
deleted file mode 100644
index 69b66c7..0000000
--- a/libc/arch-x86/kabylake/string/avx2-wmemset-kbl.S
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-Copyright (C) 2019 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-*/
-
-#include <private/bionic_asm.h>
-
-#ifndef WMEMSET
- #define WMEMSET wmemset_avx2
-#endif
-
-ENTRY(WMEMSET)
-# BB#0:
- pushl %ebp
- pushl %ebx
- pushl %edi
- pushl %esi
- pushl %eax
- movl 32(%esp), %ecx
- movl 24(%esp), %eax
- testl %ecx, %ecx
- je .LBB0_12
-# BB#1:
- movl 28(%esp), %edx
- xorl %edi, %edi
- movl %eax, %esi
- cmpl $32, %ecx
- jb .LBB0_10
-# BB#2:
- movl %ecx, %eax
- andl $-32, %eax
- vmovd %edx, %xmm0
- vpbroadcastd %xmm0, %ymm0
- movl %eax, (%esp) # 4-byte Spill
- leal -32(%eax), %esi
- movl %esi, %eax
- shrl $5, %eax
- leal 1(%eax), %edi
- andl $7, %edi
- xorl %ebx, %ebx
- cmpl $224, %esi
- jb .LBB0_5
-# BB#3:
- movl 24(%esp), %esi
- leal 992(%esi), %ebp
- leal -1(%edi), %esi
- subl %eax, %esi
- xorl %ebx, %ebx
- .p2align 4, 0x90
-.LBB0_4: # =>This Inner Loop Header: Depth=1
- vmovdqu %ymm0, -992(%ebp,%ebx,4)
- vmovdqu %ymm0, -960(%ebp,%ebx,4)
- vmovdqu %ymm0, -928(%ebp,%ebx,4)
- vmovdqu %ymm0, -896(%ebp,%ebx,4)
- vmovdqu %ymm0, -864(%ebp,%ebx,4)
- vmovdqu %ymm0, -832(%ebp,%ebx,4)
- vmovdqu %ymm0, -800(%ebp,%ebx,4)
- vmovdqu %ymm0, -768(%ebp,%ebx,4)
- vmovdqu %ymm0, -736(%ebp,%ebx,4)
- vmovdqu %ymm0, -704(%ebp,%ebx,4)
- vmovdqu %ymm0, -672(%ebp,%ebx,4)
- vmovdqu %ymm0, -640(%ebp,%ebx,4)
- vmovdqu %ymm0, -608(%ebp,%ebx,4)
- vmovdqu %ymm0, -576(%ebp,%ebx,4)
- vmovdqu %ymm0, -544(%ebp,%ebx,4)
- vmovdqu %ymm0, -512(%ebp,%ebx,4)
- vmovdqu %ymm0, -480(%ebp,%ebx,4)
- vmovdqu %ymm0, -448(%ebp,%ebx,4)
- vmovdqu %ymm0, -416(%ebp,%ebx,4)
- vmovdqu %ymm0, -384(%ebp,%ebx,4)
- vmovdqu %ymm0, -352(%ebp,%ebx,4)
- vmovdqu %ymm0, -320(%ebp,%ebx,4)
- vmovdqu %ymm0, -288(%ebp,%ebx,4)
- vmovdqu %ymm0, -256(%ebp,%ebx,4)
- vmovdqu %ymm0, -224(%ebp,%ebx,4)
- vmovdqu %ymm0, -192(%ebp,%ebx,4)
- vmovdqu %ymm0, -160(%ebp,%ebx,4)
- vmovdqu %ymm0, -128(%ebp,%ebx,4)
- vmovdqu %ymm0, -96(%ebp,%ebx,4)
- vmovdqu %ymm0, -64(%ebp,%ebx,4)
- vmovdqu %ymm0, -32(%ebp,%ebx,4)
- vmovdqu %ymm0, (%ebp,%ebx,4)
- addl $256, %ebx # imm = 0x100
- addl $8, %esi
- jne .LBB0_4
-.LBB0_5:
- testl %edi, %edi
- movl 24(%esp), %eax
- je .LBB0_8
-# BB#6:
- leal (%eax,%ebx,4), %esi
- addl $96, %esi
- negl %edi
- .p2align 4, 0x90
-.LBB0_7: # =>This Inner Loop Header: Depth=1
- vmovdqu %ymm0, -96(%esi)
- vmovdqu %ymm0, -64(%esi)
- vmovdqu %ymm0, -32(%esi)
- vmovdqu %ymm0, (%esi)
- subl $-128, %esi
- addl $1, %edi
- jne .LBB0_7
-.LBB0_8:
- movl (%esp), %edi # 4-byte Reload
- cmpl %ecx, %edi
- je .LBB0_12
-# BB#9:
- leal (%eax,%edi,4), %esi
-.LBB0_10:
- subl %edi, %ecx
- .p2align 4, 0x90
-.LBB0_11: # =>This Inner Loop Header: Depth=1
- movl %edx, (%esi)
- addl $4, %esi
- addl $-1, %ecx
- jne .LBB0_11
-.LBB0_12:
- addl $4, %esp
- popl %esi
- popl %edi
- popl %ebx
- popl %ebp
- vzeroupper
- retl
-END(WMEMSET)
diff --git a/libc/arch-x86/static_function_dispatch.S b/libc/arch-x86/static_function_dispatch.S
index 1560c04..7e8e63d 100644
--- a/libc/arch-x86/static_function_dispatch.S
+++ b/libc/arch-x86/static_function_dispatch.S
@@ -45,7 +45,6 @@
FUNCTION_DELEGATE(strncmp, strncmp_generic)
FUNCTION_DELEGATE(strcat, strcat_generic)
FUNCTION_DELEGATE(wmemcmp, wmemcmp_freebsd)
-FUNCTION_DELEGATE(wmemset, wmemset_freebsd)
FUNCTION_DELEGATE(wcscat, wcscat_freebsd)
FUNCTION_DELEGATE(strncat, strncat_openbsd)
FUNCTION_DELEGATE(strlcat, strlcat_openbsd)
diff --git a/libc/arch-x86/silvermont/string/cache.h b/libc/arch-x86/string/cache.h
similarity index 80%
rename from libc/arch-x86/silvermont/string/cache.h
rename to libc/arch-x86/string/cache.h
index c342b1c..33719a0 100644
--- a/libc/arch-x86/silvermont/string/cache.h
+++ b/libc/arch-x86/string/cache.h
@@ -28,9 +28,14 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* Values are optimized for Silvermont */
-#define SHARED_CACHE_SIZE (1024*1024) /* Silvermont L2 Cache */
-#define DATA_CACHE_SIZE (24*1024) /* Silvermont L1 Data Cache */
+#ifdef FOR_ATOM
+#define SHARED_CACHE_SIZE (512 * 1024) /* Atom L2 Cache */
+#endif
+#ifdef FOR_SILVERMONT
+#define SHARED_CACHE_SIZE (1024 * 1024) /* Silvermont L2 Cache */
+#endif
-#define SHARED_CACHE_SIZE_HALF (SHARED_CACHE_SIZE / 2)
-#define DATA_CACHE_SIZE_HALF (DATA_CACHE_SIZE / 2)
+#define DATA_CACHE_SIZE (24 * 1024) /* Atom and Silvermont L1 Data Cache */
+
+#define SHARED_CACHE_SIZE_HALF (SHARED_CACHE_SIZE / 2)
+#define DATA_CACHE_SIZE_HALF (DATA_CACHE_SIZE / 2)
diff --git a/libc/arch-x86/atom/string/sse2-memchr-atom.S b/libc/arch-x86/string/sse2-memchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-memchr-atom.S
rename to libc/arch-x86/string/sse2-memchr-atom.S
diff --git a/libc/arch-x86/silvermont/string/sse2-memmove-slm.S b/libc/arch-x86/string/sse2-memmove-slm.S
similarity index 99%
rename from libc/arch-x86/silvermont/string/sse2-memmove-slm.S
rename to libc/arch-x86/string/sse2-memmove-slm.S
index da6456c..79b5d1b 100644
--- a/libc/arch-x86/silvermont/string/sse2-memmove-slm.S
+++ b/libc/arch-x86/string/sse2-memmove-slm.S
@@ -28,6 +28,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define FOR_SILVERMONT
#include "cache.h"
#ifndef MEMMOVE
diff --git a/libc/arch-x86/atom/string/sse2-memrchr-atom.S b/libc/arch-x86/string/sse2-memrchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-memrchr-atom.S
rename to libc/arch-x86/string/sse2-memrchr-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-memset-atom.S b/libc/arch-x86/string/sse2-memset-atom.S
similarity index 99%
rename from libc/arch-x86/atom/string/sse2-memset-atom.S
rename to libc/arch-x86/string/sse2-memset-atom.S
index e4cd038..320afec 100644
--- a/libc/arch-x86/atom/string/sse2-memset-atom.S
+++ b/libc/arch-x86/string/sse2-memset-atom.S
@@ -30,6 +30,7 @@
#include <private/bionic_asm.h>
+#define FOR_ATOM
#include "cache.h"
#ifndef L
diff --git a/libc/arch-x86/silvermont/string/sse2-memset-slm.S b/libc/arch-x86/string/sse2-memset-slm.S
similarity index 99%
rename from libc/arch-x86/silvermont/string/sse2-memset-slm.S
rename to libc/arch-x86/string/sse2-memset-slm.S
index b7633f5..5cff141 100644
--- a/libc/arch-x86/silvermont/string/sse2-memset-slm.S
+++ b/libc/arch-x86/string/sse2-memset-slm.S
@@ -30,6 +30,7 @@
#include <private/bionic_asm.h>
+#define FOR_SILVERMONT
#include "cache.h"
#ifndef L
diff --git a/libc/arch-x86/silvermont/string/sse2-stpcpy-slm.S b/libc/arch-x86/string/sse2-stpcpy-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-stpcpy-slm.S
rename to libc/arch-x86/string/sse2-stpcpy-slm.S
diff --git a/libc/arch-x86/silvermont/string/sse2-stpncpy-slm.S b/libc/arch-x86/string/sse2-stpncpy-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-stpncpy-slm.S
rename to libc/arch-x86/string/sse2-stpncpy-slm.S
diff --git a/libc/arch-x86/atom/string/sse2-strchr-atom.S b/libc/arch-x86/string/sse2-strchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-strchr-atom.S
rename to libc/arch-x86/string/sse2-strchr-atom.S
diff --git a/libc/arch-x86/silvermont/string/sse2-strcpy-slm.S b/libc/arch-x86/string/sse2-strcpy-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-strcpy-slm.S
rename to libc/arch-x86/string/sse2-strcpy-slm.S
diff --git a/libc/arch-x86/atom/string/sse2-strlen-atom.S b/libc/arch-x86/string/sse2-strlen-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-strlen-atom.S
rename to libc/arch-x86/string/sse2-strlen-atom.S
diff --git a/libc/arch-x86/silvermont/string/sse2-strlen-slm.S b/libc/arch-x86/string/sse2-strlen-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-strlen-slm.S
rename to libc/arch-x86/string/sse2-strlen-slm.S
diff --git a/libc/arch-x86/silvermont/string/sse2-strncpy-slm.S b/libc/arch-x86/string/sse2-strncpy-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse2-strncpy-slm.S
rename to libc/arch-x86/string/sse2-strncpy-slm.S
diff --git a/libc/arch-x86/atom/string/sse2-strnlen-atom.S b/libc/arch-x86/string/sse2-strnlen-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-strnlen-atom.S
rename to libc/arch-x86/string/sse2-strnlen-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-strrchr-atom.S b/libc/arch-x86/string/sse2-strrchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-strrchr-atom.S
rename to libc/arch-x86/string/sse2-strrchr-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-wcschr-atom.S b/libc/arch-x86/string/sse2-wcschr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-wcschr-atom.S
rename to libc/arch-x86/string/sse2-wcschr-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-wcscmp-atom.S b/libc/arch-x86/string/sse2-wcscmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-wcscmp-atom.S
rename to libc/arch-x86/string/sse2-wcscmp-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-wcslen-atom.S b/libc/arch-x86/string/sse2-wcslen-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-wcslen-atom.S
rename to libc/arch-x86/string/sse2-wcslen-atom.S
diff --git a/libc/arch-x86/atom/string/sse2-wcsrchr-atom.S b/libc/arch-x86/string/sse2-wcsrchr-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/sse2-wcsrchr-atom.S
rename to libc/arch-x86/string/sse2-wcsrchr-atom.S
diff --git a/libc/arch-x86/silvermont/string/sse4-memcmp-slm.S b/libc/arch-x86/string/sse4-memcmp-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse4-memcmp-slm.S
rename to libc/arch-x86/string/sse4-memcmp-slm.S
diff --git a/libc/arch-x86/silvermont/string/sse4-wmemcmp-slm.S b/libc/arch-x86/string/sse4-wmemcmp-slm.S
similarity index 100%
rename from libc/arch-x86/silvermont/string/sse4-wmemcmp-slm.S
rename to libc/arch-x86/string/sse4-wmemcmp-slm.S
diff --git a/libc/arch-x86/atom/string/ssse3-memcmp-atom.S b/libc/arch-x86/string/ssse3-memcmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-memcmp-atom.S
rename to libc/arch-x86/string/ssse3-memcmp-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-memcpy-atom.S b/libc/arch-x86/string/ssse3-memcpy-atom.S
similarity index 99%
rename from libc/arch-x86/atom/string/ssse3-memcpy-atom.S
rename to libc/arch-x86/string/ssse3-memcpy-atom.S
index 5532e2e..fe3082e 100644
--- a/libc/arch-x86/atom/string/ssse3-memcpy-atom.S
+++ b/libc/arch-x86/string/ssse3-memcpy-atom.S
@@ -28,6 +28,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define FOR_ATOM
#include "cache.h"
#ifndef MEMCPY
diff --git a/libc/arch-x86/atom/string/ssse3-memmove-atom.S b/libc/arch-x86/string/ssse3-memmove-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-memmove-atom.S
rename to libc/arch-x86/string/ssse3-memmove-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strcat-atom.S b/libc/arch-x86/string/ssse3-strcat-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strcat-atom.S
rename to libc/arch-x86/string/ssse3-strcat-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strcmp-atom.S b/libc/arch-x86/string/ssse3-strcmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strcmp-atom.S
rename to libc/arch-x86/string/ssse3-strcmp-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strcpy-atom.S b/libc/arch-x86/string/ssse3-strcpy-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strcpy-atom.S
rename to libc/arch-x86/string/ssse3-strcpy-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strlcat-atom.S b/libc/arch-x86/string/ssse3-strlcat-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strlcat-atom.S
rename to libc/arch-x86/string/ssse3-strlcat-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strlcpy-atom.S b/libc/arch-x86/string/ssse3-strlcpy-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strlcpy-atom.S
rename to libc/arch-x86/string/ssse3-strlcpy-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strncat-atom.S b/libc/arch-x86/string/ssse3-strncat-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strncat-atom.S
rename to libc/arch-x86/string/ssse3-strncat-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strncmp-atom.S b/libc/arch-x86/string/ssse3-strncmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strncmp-atom.S
rename to libc/arch-x86/string/ssse3-strncmp-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-strncpy-atom.S b/libc/arch-x86/string/ssse3-strncpy-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-strncpy-atom.S
rename to libc/arch-x86/string/ssse3-strncpy-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-wcscat-atom.S b/libc/arch-x86/string/ssse3-wcscat-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-wcscat-atom.S
rename to libc/arch-x86/string/ssse3-wcscat-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-wcscpy-atom.S b/libc/arch-x86/string/ssse3-wcscpy-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-wcscpy-atom.S
rename to libc/arch-x86/string/ssse3-wcscpy-atom.S
diff --git a/libc/arch-x86/atom/string/ssse3-wmemcmp-atom.S b/libc/arch-x86/string/ssse3-wmemcmp-atom.S
similarity index 100%
rename from libc/arch-x86/atom/string/ssse3-wmemcmp-atom.S
rename to libc/arch-x86/string/ssse3-wmemcmp-atom.S
diff --git a/libc/arch-x86_64/dynamic_function_dispatch.cpp b/libc/arch-x86_64/dynamic_function_dispatch.cpp
new file mode 100644
index 0000000..c846ded
--- /dev/null
+++ b/libc/arch-x86_64/dynamic_function_dispatch.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+
+#include <private/bionic_ifuncs.h>
+
+extern "C" {
+
+typedef int memset_func(void* __dst, int __ch, size_t __n);
+DEFINE_IFUNC_FOR(memset) {
+ __builtin_cpu_init();
+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memset_func, memset_avx2);
+ RETURN_FUNC(memset_func, memset_generic);
+}
+
+typedef void* __memset_chk_func(void* s, int c, size_t n, size_t n2);
+DEFINE_IFUNC_FOR(__memset_chk) {
+ __builtin_cpu_init();
+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(__memset_chk_func, __memset_chk_avx2);
+ RETURN_FUNC(__memset_chk_func, __memset_chk_generic);
+}
+
+} // extern "C"
diff --git a/libc/arch-x86_64/static_function_dispatch.S b/libc/arch-x86_64/static_function_dispatch.S
new file mode 100644
index 0000000..93ff5f2
--- /dev/null
+++ b/libc/arch-x86_64/static_function_dispatch.S
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+
+#define FUNCTION_DELEGATE(name, impl) \
+ENTRY(name); \
+ jmp impl; \
+END(name)
+
+FUNCTION_DELEGATE(memset, memset_generic)
+FUNCTION_DELEGATE(__memset_chk, __memset_chk_generic)
diff --git a/libc/arch-x86_64/string/avx2-memset-kbl.S b/libc/arch-x86_64/string/avx2-memset-kbl.S
new file mode 100644
index 0000000..09dd07d
--- /dev/null
+++ b/libc/arch-x86_64/string/avx2-memset-kbl.S
@@ -0,0 +1,160 @@
+/*
+Copyright (c) 2014, Intel Corporation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+
+ * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <private/bionic_asm.h>
+
+#include "cache.h"
+
+#ifndef L
+# define L(label) .L##label
+#endif
+
+#ifndef ALIGN
+# define ALIGN(n) .p2align n
+#endif
+
+ .section .text.avx2,"ax",@progbits
+
+ENTRY(__memset_chk_avx2)
+ # %rdi = dst, %rsi = byte, %rdx = n, %rcx = dst_len
+ cmp %rcx, %rdx
+ ja __memset_chk_fail
+ // Fall through to memset...
+END(__memset_chk_avx2)
+
+ENTRY(memset_avx2)
+ movq %rdi, %rax
+ and $0xff, %rsi
+ mov $0x0101010101010101, %rcx
+ imul %rsi, %rcx
+ cmpq $16, %rdx
+ jae L(16bytesormore)
+ testb $8, %dl
+ jnz L(8_15bytes)
+ testb $4, %dl
+ jnz L(4_7bytes)
+ testb $2, %dl
+ jnz L(2_3bytes)
+ testb $1, %dl
+ jz L(return)
+ movb %cl, (%rdi)
+L(return):
+ ret
+
+L(8_15bytes):
+ movq %rcx, (%rdi)
+ movq %rcx, -8(%rdi, %rdx)
+ ret
+
+L(4_7bytes):
+ movl %ecx, (%rdi)
+ movl %ecx, -4(%rdi, %rdx)
+ ret
+
+L(2_3bytes):
+ movw %cx, (%rdi)
+ movw %cx, -2(%rdi, %rdx)
+ ret
+
+ ALIGN (4)
+L(16bytesormore):
+ movd %rcx, %xmm0
+ pshufd $0, %xmm0, %xmm0
+ movdqu %xmm0, (%rdi)
+ movdqu %xmm0, -16(%rdi, %rdx)
+ cmpq $32, %rdx
+ jbe L(32bytesless)
+ movdqu %xmm0, 16(%rdi)
+ movdqu %xmm0, -32(%rdi, %rdx)
+ cmpq $64, %rdx
+ jbe L(64bytesless)
+ movdqu %xmm0, 32(%rdi)
+ movdqu %xmm0, 48(%rdi)
+ movdqu %xmm0, -64(%rdi, %rdx)
+ movdqu %xmm0, -48(%rdi, %rdx)
+ cmpq $128, %rdx
+ jbe L(128bytesless)
+ vpbroadcastb %xmm0, %ymm0
+ vmovdqu %ymm0, 64(%rdi)
+ vmovdqu %ymm0, 96(%rdi)
+ vmovdqu %ymm0, -128(%rdi, %rdx)
+ vmovdqu %ymm0, -96(%rdi, %rdx)
+ cmpq $256, %rdx
+ ja L(256bytesmore)
+L(32bytesless):
+L(64bytesless):
+L(128bytesless):
+ ret
+
+ ALIGN (4)
+L(256bytesmore):
+ leaq 128(%rdi), %rcx
+ andq $-128, %rcx
+ movq %rdx, %r8
+ addq %rdi, %rdx
+ andq $-128, %rdx
+ cmpq %rcx, %rdx
+ je L(return)
+
+#ifdef SHARED_CACHE_SIZE
+ cmp $SHARED_CACHE_SIZE, %r8
+#else
+ cmp __x86_64_shared_cache_size(%rip), %r8
+#endif
+ ja L(256bytesmore_nt)
+
+ ALIGN (4)
+L(256bytesmore_normal):
+ vmovdqa %ymm0, (%rcx)
+ vmovdqa %ymm0, 32(%rcx)
+ vmovdqa %ymm0, 64(%rcx)
+ vmovdqa %ymm0, 96(%rcx)
+ addq $128, %rcx
+ cmpq %rcx, %rdx
+ jne L(256bytesmore_normal)
+ ret
+
+ ALIGN (4)
+L(256bytesmore_nt):
+ movntdq %xmm0, (%rcx)
+ movntdq %xmm0, 16(%rcx)
+ movntdq %xmm0, 32(%rcx)
+ movntdq %xmm0, 48(%rcx)
+ movntdq %xmm0, 64(%rcx)
+ movntdq %xmm0, 80(%rcx)
+ movntdq %xmm0, 96(%rcx)
+ movntdq %xmm0, 112(%rcx)
+ leaq 128(%rcx), %rcx
+ cmpq %rcx, %rdx
+ jne L(256bytesmore_nt)
+ sfence
+ ret
+
+END(memset_avx2)
diff --git a/libc/arch-x86_64/string/avx2-wmemset-kbl.S b/libc/arch-x86_64/string/avx2-wmemset-kbl.S
deleted file mode 100644
index 7c485cf..0000000
--- a/libc/arch-x86_64/string/avx2-wmemset-kbl.S
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-Copyright (C) 2019 The Android Open Source Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-*/
-
-#include <private/bionic_asm.h>
-
-#ifndef WMEMSET
- #define WMEMSET wmemset_avx2
-#endif
-
- .section .text.avx2,"ax",@progbits
-
-ENTRY (WMEMSET)
-# BB#0:
- testq %rdx, %rdx
- je .LBB0_14
-# BB#1:
- cmpq $32, %rdx
- jae .LBB0_3
-# BB#2:
- xorl %r8d, %r8d
- movq %rdi, %rax
- jmp .LBB0_12
-.LBB0_3:
- movq %rdx, %r8
- andq $-32, %r8
- vmovd %esi, %xmm0
- vpbroadcastd %xmm0, %ymm0
- leaq -32(%r8), %rcx
- movq %rcx, %rax
- shrq $5, %rax
- leal 1(%rax), %r9d
- andl $7, %r9d
- cmpq $224, %rcx
- jae .LBB0_5
-# BB#4:
- xorl %eax, %eax
- testq %r9, %r9
- jne .LBB0_8
- jmp .LBB0_10
-.LBB0_5:
- leaq 992(%rdi), %rcx
- leaq -1(%r9), %r10
- subq %rax, %r10
- xorl %eax, %eax
- .p2align 4, 0x90
-.LBB0_6: # =>This Inner Loop Header: Depth=1
- vmovdqu %ymm0, -992(%rcx,%rax,4)
- vmovdqu %ymm0, -960(%rcx,%rax,4)
- vmovdqu %ymm0, -928(%rcx,%rax,4)
- vmovdqu %ymm0, -896(%rcx,%rax,4)
- vmovdqu %ymm0, -864(%rcx,%rax,4)
- vmovdqu %ymm0, -832(%rcx,%rax,4)
- vmovdqu %ymm0, -800(%rcx,%rax,4)
- vmovdqu %ymm0, -768(%rcx,%rax,4)
- vmovdqu %ymm0, -736(%rcx,%rax,4)
- vmovdqu %ymm0, -704(%rcx,%rax,4)
- vmovdqu %ymm0, -672(%rcx,%rax,4)
- vmovdqu %ymm0, -640(%rcx,%rax,4)
- vmovdqu %ymm0, -608(%rcx,%rax,4)
- vmovdqu %ymm0, -576(%rcx,%rax,4)
- vmovdqu %ymm0, -544(%rcx,%rax,4)
- vmovdqu %ymm0, -512(%rcx,%rax,4)
- vmovdqu %ymm0, -480(%rcx,%rax,4)
- vmovdqu %ymm0, -448(%rcx,%rax,4)
- vmovdqu %ymm0, -416(%rcx,%rax,4)
- vmovdqu %ymm0, -384(%rcx,%rax,4)
- vmovdqu %ymm0, -352(%rcx,%rax,4)
- vmovdqu %ymm0, -320(%rcx,%rax,4)
- vmovdqu %ymm0, -288(%rcx,%rax,4)
- vmovdqu %ymm0, -256(%rcx,%rax,4)
- vmovdqu %ymm0, -224(%rcx,%rax,4)
- vmovdqu %ymm0, -192(%rcx,%rax,4)
- vmovdqu %ymm0, -160(%rcx,%rax,4)
- vmovdqu %ymm0, -128(%rcx,%rax,4)
- vmovdqu %ymm0, -96(%rcx,%rax,4)
- vmovdqu %ymm0, -64(%rcx,%rax,4)
- vmovdqu %ymm0, -32(%rcx,%rax,4)
- vmovdqu %ymm0, (%rcx,%rax,4)
- addq $256, %rax # imm = 0x100
- addq $8, %r10
- jne .LBB0_6
-# BB#7:
- testq %r9, %r9
- je .LBB0_10
-.LBB0_8:
- leaq (%rdi,%rax,4), %rax
- addq $96, %rax
- negq %r9
- .p2align 4, 0x90
-.LBB0_9: # =>This Inner Loop Header: Depth=1
- vmovdqu %ymm0, -96(%rax)
- vmovdqu %ymm0, -64(%rax)
- vmovdqu %ymm0, -32(%rax)
- vmovdqu %ymm0, (%rax)
- subq $-128, %rax
- addq $1, %r9
- jne .LBB0_9
-.LBB0_10:
- cmpq %rdx, %r8
- je .LBB0_14
-# BB#11:
- leaq (%rdi,%r8,4), %rax
-.LBB0_12:
- subq %r8, %rdx
- .p2align 4, 0x90
-.LBB0_13: # =>This Inner Loop Header: Depth=1
- movl %esi, (%rax)
- addq $4, %rax
- addq $-1, %rdx
- jne .LBB0_13
-.LBB0_14:
- movq %rdi, %rax
- vzeroupper
- retq
-END(WMEMSET)
diff --git a/libc/arch-x86_64/string/sse2-memset-slm.S b/libc/arch-x86_64/string/sse2-memset-slm.S
index fc502c0..cceadd2 100644
--- a/libc/arch-x86_64/string/sse2-memset-slm.S
+++ b/libc/arch-x86_64/string/sse2-memset-slm.S
@@ -41,16 +41,16 @@
#endif
-ENTRY(__memset_chk)
+ENTRY(__memset_chk_generic)
# %rdi = dst, %rsi = byte, %rdx = n, %rcx = dst_len
cmp %rcx, %rdx
ja __memset_chk_fail
// Fall through to memset...
-END(__memset_chk)
+END(__memset_chk_generic)
.section .text.sse2,"ax",@progbits
-ENTRY(memset)
+ENTRY(memset_generic)
movq %rdi, %rax
and $0xff, %rsi
mov $0x0101010101010101, %rcx
@@ -146,4 +146,4 @@
sfence
ret
-END(memset)
+END(memset_generic)
diff --git a/libc/async_safe/Android.bp b/libc/async_safe/Android.bp
index 531317d..eb690dd 100644
--- a/libc/async_safe/Android.bp
+++ b/libc/async_safe/Android.bp
@@ -30,13 +30,8 @@
stl: "none",
apex_available: [
+ "//apex_available:anyapex",
"//apex_available:platform",
- "com.android.runtime",
- "com.android.art",
- "com.android.art.debug",
- "com.android.media",
- "com.android.media.swcodec",
- "com.android.virt",
],
min_sdk_version: "apex_inherit",
}
diff --git a/libc/bionic/android_profiling_dynamic.cpp b/libc/bionic/android_profiling_dynamic.cpp
index 3460a6d..8c9127e 100644
--- a/libc/bionic/android_profiling_dynamic.cpp
+++ b/libc/bionic/android_profiling_dynamic.cpp
@@ -204,12 +204,14 @@
auto ret = -ENOSYS;
ucontext_t* ctx = reinterpret_cast<ucontext_t*>(void_context);
-#if defined(__arm__)
+#if defined(__aarch64__)
+ ctx->uc_mcontext.regs[0] = ret;
+#elif defined(__arm__)
ctx->uc_mcontext.arm_r0 = ret;
-#elif defined(__aarch64__)
- ctx->uc_mcontext.regs[0] = ret; // x0
#elif defined(__i386__)
ctx->uc_mcontext.gregs[REG_EAX] = ret;
+#elif defined(__riscv)
+ ctx->uc_mcontext.__gregs[REG_A0] = ret;
#elif defined(__x86_64__)
ctx->uc_mcontext.gregs[REG_RAX] = ret;
#else
diff --git a/libc/bionic/bionic_elf_tls.cpp b/libc/bionic/bionic_elf_tls.cpp
index d5fb05a..79893e3 100644
--- a/libc/bionic/bionic_elf_tls.cpp
+++ b/libc/bionic/bionic_elf_tls.cpp
@@ -137,6 +137,15 @@
offset_bionic_tcb_ = reserve(sizeof(bionic_tcb), max_align);
return offset_bionic_tcb_ - exe_size;
+#elif defined(__riscv)
+
+ // First reserve enough space for the TCB before the executable segment.
+ offset_bionic_tcb_ = reserve(sizeof(bionic_tcb), 1);
+
+ // Then reserve the segment itself.
+ const size_t exe_size = round_up_with_overflow_check(exe_segment->size, exe_segment->alignment);
+ return reserve(exe_size, 1);
+
#else
#error "Unrecognized architecture"
#endif
@@ -312,7 +321,7 @@
}
}
- return static_cast<char*>(mod_ptr) + ti->offset;
+ return static_cast<char*>(mod_ptr) + ti->offset + TLS_DTV_OFFSET;
}
// Returns the address of a thread's TLS memory given a module ID and an offset
@@ -332,7 +341,7 @@
if (__predict_true(generation == dtv->generation)) {
void* mod_ptr = dtv->modules[__tls_module_id_to_idx(ti->module_id)];
if (__predict_true(mod_ptr != nullptr)) {
- return static_cast<char*>(mod_ptr) + ti->offset;
+ return static_cast<char*>(mod_ptr) + ti->offset + TLS_DTV_OFFSET;
}
}
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index fd2c401..40612e7 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -39,10 +39,12 @@
#include <string.h>
#include <unistd.h>
-#include "private/__bionic_get_shell_path.h"
#include "private/FdPath.h"
+#include "private/__bionic_get_shell_path.h"
+#include "pthread_internal.h"
extern "C" char** environ;
+extern "C" int __execve(const char* pathname, char* const* argv, char* const* envp);
enum { ExecL, ExecLE, ExecLP };
@@ -181,3 +183,9 @@
if (errno == ENOENT) errno = EBADF;
return -1;
}
+
+__attribute__((no_sanitize("memtag"))) int execve(const char* pathname, char* const* argv,
+ char* const* envp) {
+ __get_thread()->vfork_child_stack_bottom = __builtin_frame_address(0);
+ return __execve(pathname, argv, envp);
+}
diff --git a/libc/bionic/exit.cpp b/libc/bionic/exit.cpp
index a5aed78..52fd193 100644
--- a/libc/bionic/exit.cpp
+++ b/libc/bionic/exit.cpp
@@ -30,9 +30,18 @@
#include <unistd.h>
#include "private/bionic_defs.h"
+#include "pthread_internal.h"
extern "C" void __cxa_finalize(void* dso_handle);
extern "C" void __cxa_thread_finalize();
+extern "C" __noreturn void __exit_group(int status);
+
+__attribute__((no_sanitize("memtag"))) void _exit(int status) {
+ __get_thread()->vfork_child_stack_bottom = __builtin_frame_address(0);
+ __exit_group(status);
+}
+
+__strong_alias(_Exit, _exit);
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
void exit(int status) {
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 48e8674..6433b59 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -101,7 +101,7 @@
}
size_t offset = idx - inline_fds;
- if (local_overflow->len < offset) {
+ if (local_overflow->len <= offset) {
return nullptr;
}
return &local_overflow->entries[offset];
@@ -216,6 +216,8 @@
return "SocketImpl";
case ANDROID_FDSAN_OWNER_TYPE_ZIPARCHIVE:
return "ZipArchive";
+ case ANDROID_FDSAN_OWNER_TYPE_NATIVE_HANDLE:
+ return "native_handle_t";
case ANDROID_FDSAN_OWNER_TYPE_GENERIC_00:
default:
diff --git a/libc/bionic/gwp_asan_wrappers.cpp b/libc/bionic/gwp_asan_wrappers.cpp
index 7e19b31..fc59c88 100644
--- a/libc/bionic/gwp_asan_wrappers.cpp
+++ b/libc/bionic/gwp_asan_wrappers.cpp
@@ -41,6 +41,7 @@
#include "gwp_asan_wrappers.h"
#include "malloc_common.h"
#include "platform/bionic/android_unsafe_frame_pointer_chase.h"
+#include "platform/bionic/macros.h"
#include "platform/bionic/malloc.h"
#include "private/bionic_arc4random.h"
#include "private/bionic_globals.h"
@@ -221,6 +222,8 @@
static const char* kMaxAllocsTargetedSyspropPrefix = "libc.debug.gwp_asan.max_allocs.";
static const char* kMaxAllocsEnvVar = "GWP_ASAN_MAX_ALLOCS";
+static const char kPersistPrefix[] = "persist.";
+
void SetDefaultGwpAsanOptions(Options* options, unsigned* process_sample_rate,
const android_mallopt_gwp_asan_options_t& mallopt_options) {
options->Enabled = true;
@@ -244,26 +247,40 @@
const char* basename = "";
if (mallopt_options.program_name) basename = __gnu_basename(mallopt_options.program_name);
- size_t program_specific_sysprop_size = strlen(targeted_sysprop_prefix) + strlen(basename) + 1;
- char* program_specific_sysprop_name = static_cast<char*>(alloca(program_specific_sysprop_size));
- async_safe_format_buffer(program_specific_sysprop_name, program_specific_sysprop_size, "%s%s",
- targeted_sysprop_prefix, basename);
-
- const char* sysprop_names[2] = {nullptr, nullptr};
+ constexpr size_t kSyspropMaxLen = 512;
+ char program_specific_sysprop[kSyspropMaxLen] = {};
+ char persist_program_specific_sysprop[kSyspropMaxLen] = {};
+ char persist_default_sysprop[kSyspropMaxLen] = {};
+ const char* sysprop_names[4] = {};
// Tests use a blank program name to specify that system properties should not
// be used. Tests still continue to use the environment variable though.
if (*basename != '\0') {
- sysprop_names[0] = program_specific_sysprop_name;
+ const char* default_sysprop = system_sysprop;
if (mallopt_options.desire == Action::TURN_ON_FOR_APP) {
- sysprop_names[1] = app_sysprop;
- } else {
- sysprop_names[1] = system_sysprop;
+ default_sysprop = app_sysprop;
}
+ async_safe_format_buffer(&program_specific_sysprop[0], kSyspropMaxLen, "%s%s",
+ targeted_sysprop_prefix, basename);
+ async_safe_format_buffer(&persist_program_specific_sysprop[0], kSyspropMaxLen, "%s%s",
+ kPersistPrefix, program_specific_sysprop);
+ async_safe_format_buffer(&persist_default_sysprop[0], kSyspropMaxLen, "%s%s", kPersistPrefix,
+ default_sysprop);
+
+ // In order of precedence, always take the program-specific sysprop (e.g.
+ // '[persist.]libc.debug.gwp_asan.sample_rate.cameraserver') over the
+ // generic sysprop (e.g.
+ // '[persist.]libc.debug.gwp_asan.(system_default|app_default)'). In
+ // addition, always take the non-persistent option over the persistent
+ // option.
+ sysprop_names[0] = program_specific_sysprop;
+ sysprop_names[1] = persist_program_specific_sysprop;
+ sysprop_names[2] = default_sysprop;
+ sysprop_names[3] = persist_default_sysprop;
}
char settings_buf[PROP_VALUE_MAX];
- if (!get_config_from_env_or_sysprops(env_var, sysprop_names,
- /* sys_prop_names_size */ 2, settings_buf, PROP_VALUE_MAX)) {
+ if (!get_config_from_env_or_sysprops(env_var, sysprop_names, arraysize(sysprop_names),
+ settings_buf, PROP_VALUE_MAX)) {
return false;
}
diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp
index 41aa205..78d21b0 100644
--- a/libc/bionic/heap_tagging.cpp
+++ b/libc/bionic/heap_tagging.cpp
@@ -32,6 +32,8 @@
#include <bionic/pthread_internal.h>
#include <platform/bionic/malloc.h>
+#include <sanitizer/hwasan_interface.h>
+#include <sys/auxv.h>
extern "C" void scudo_malloc_disable_memory_tagging();
extern "C" void scudo_malloc_set_track_allocation_stacks(int);
@@ -44,61 +46,61 @@
#if !__has_feature(hwaddress_sanitizer)
heap_tagging_level = __libc_shared_globals()->initial_heap_tagging_level;
#endif
- switch (heap_tagging_level) {
- case M_HEAP_TAGGING_LEVEL_TBI:
- __libc_globals.mutate([](libc_globals* globals) {
+
+ __libc_globals.mutate([](libc_globals* globals) {
+ switch (heap_tagging_level) {
+ case M_HEAP_TAGGING_LEVEL_TBI:
// Arrange for us to set pointer tags to POINTER_TAG, check tags on
// deallocation and untag when passing pointers to the allocator.
globals->heap_pointer_tag = (reinterpret_cast<uintptr_t>(POINTER_TAG) << TAG_SHIFT) |
(0xffull << CHECK_SHIFT) | (0xffull << UNTAG_SHIFT);
- });
-#if defined(USE_SCUDO)
- scudo_malloc_disable_memory_tagging();
-#endif // USE_SCUDO
- break;
-#if defined(USE_SCUDO)
- case M_HEAP_TAGGING_LEVEL_SYNC:
- scudo_malloc_set_track_allocation_stacks(1);
- break;
+ break;
+ case M_HEAP_TAGGING_LEVEL_SYNC:
+ case M_HEAP_TAGGING_LEVEL_ASYNC:
+ atomic_store(&globals->memtag_stack, __libc_shared_globals()->initial_memtag_stack);
+ break;
+ default:
+ break;
+ };
+ });
+#if defined(USE_SCUDO)
+ switch (heap_tagging_level) {
+ case M_HEAP_TAGGING_LEVEL_TBI:
case M_HEAP_TAGGING_LEVEL_NONE:
scudo_malloc_disable_memory_tagging();
break;
-#endif // USE_SCUDO
+ case M_HEAP_TAGGING_LEVEL_SYNC:
+ scudo_malloc_set_track_allocation_stacks(1);
+ break;
default:
break;
}
+#endif // USE_SCUDO
#endif // aarch64
}
static bool set_tcf_on_all_threads(int tcf) {
- static int g_tcf;
- g_tcf = tcf;
-
return android_run_on_all_threads(
- [](void*) {
+ [](void* arg) {
+ int tcf = *reinterpret_cast<int*>(arg);
int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
if (tagged_addr_ctrl < 0) {
return false;
}
- tagged_addr_ctrl = (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | g_tcf;
+ tagged_addr_ctrl = (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | tcf;
if (prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) < 0) {
return false;
}
return true;
},
- nullptr);
+ &tcf);
}
pthread_mutex_t g_heap_tagging_lock = PTHREAD_MUTEX_INITIALIZER;
// Requires `g_heap_tagging_lock` to be held.
-HeapTaggingLevel GetHeapTaggingLevel() {
- return heap_tagging_level;
-}
-
-// Requires `g_heap_tagging_lock` to be held.
bool SetHeapTaggingLevel(HeapTaggingLevel tag_level) {
if (tag_level == heap_tagging_level) {
return true;
@@ -106,16 +108,21 @@
switch (tag_level) {
case M_HEAP_TAGGING_LEVEL_NONE:
- if (heap_tagging_level == M_HEAP_TAGGING_LEVEL_TBI) {
- __libc_globals.mutate([](libc_globals* globals) {
+ __libc_globals.mutate([](libc_globals* globals) {
+ if (heap_tagging_level == M_HEAP_TAGGING_LEVEL_TBI) {
// Preserve the untag mask (we still want to untag pointers when passing them to the
// allocator), but clear the fixed tag and the check mask, so that pointers are no longer
// tagged and checks no longer happen.
globals->heap_pointer_tag = static_cast<uintptr_t>(0xffull << UNTAG_SHIFT);
- });
- } else if (!set_tcf_on_all_threads(PR_MTE_TCF_NONE)) {
- error_log("SetHeapTaggingLevel: set_tcf_on_all_threads failed");
- return false;
+ }
+ atomic_store(&globals->memtag_stack, false);
+ });
+
+ if (heap_tagging_level != M_HEAP_TAGGING_LEVEL_TBI) {
+ if (!set_tcf_on_all_threads(PR_MTE_TCF_NONE)) {
+ error_log("SetHeapTaggingLevel: set_tcf_on_all_threads failed");
+ return false;
+ }
}
#if defined(USE_SCUDO)
scudo_malloc_disable_memory_tagging();
@@ -165,3 +172,69 @@
return true;
}
+
+#ifdef __aarch64__
+static inline __attribute__((no_sanitize("memtag"))) void untag_memory(void* from, void* to) {
+ __asm__ __volatile__(
+ ".arch_extension mte\n"
+ "1:\n"
+ "stg %[Ptr], [%[Ptr]], #16\n"
+ "cmp %[Ptr], %[End]\n"
+ "b.lt 1b\n"
+ : [Ptr] "+&r"(from)
+ : [End] "r"(to)
+ : "memory");
+}
+#endif
+
+#ifdef __aarch64__
+// 128Mb of stack should be enough for anybody.
+static constexpr size_t kUntagLimit = 128 * 1024 * 1024;
+#endif // __aarch64__
+
+extern "C" __LIBC_HIDDEN__ __attribute__((no_sanitize("memtag"))) void memtag_handle_longjmp(
+ void* sp_dst __unused) {
+#ifdef __aarch64__
+ if (__libc_globals->memtag_stack) {
+ void* sp = __builtin_frame_address(0);
+ size_t distance = reinterpret_cast<uintptr_t>(sp_dst) - reinterpret_cast<uintptr_t>(sp);
+ if (distance > kUntagLimit) {
+ async_safe_fatal(
+ "memtag_handle_longjmp: stack adjustment too large! %p -> %p, distance %zx > %zx\n", sp,
+ sp_dst, distance, kUntagLimit);
+ } else {
+ untag_memory(sp, sp_dst);
+ }
+ }
+#endif // __aarch64__
+
+#if __has_feature(hwaddress_sanitizer)
+ __hwasan_handle_longjmp(sp_dst);
+#endif // __has_feature(hwaddress_sanitizer)
+}
+
+extern "C" __LIBC_HIDDEN__ __attribute__((no_sanitize("memtag"), no_sanitize("hwaddress"))) void
+memtag_handle_vfork(void* sp __unused) {
+#ifdef __aarch64__
+ if (__libc_globals->memtag_stack) {
+ void* child_sp = __get_thread()->vfork_child_stack_bottom;
+ __get_thread()->vfork_child_stack_bottom = nullptr;
+ if (child_sp) {
+ size_t distance = reinterpret_cast<uintptr_t>(sp) - reinterpret_cast<uintptr_t>(child_sp);
+ if (distance > kUntagLimit) {
+ async_safe_fatal(
+ "memtag_handle_vfork: stack adjustment too large! %p -> %p, distance %zx > %zx\n",
+ child_sp, sp, distance, kUntagLimit);
+ } else {
+ untag_memory(child_sp, sp);
+ }
+ } else {
+ async_safe_fatal("memtag_handle_vfork: child SP unknown\n");
+ }
+ }
+#endif // __aarch64__
+
+#if __has_feature(hwaddress_sanitizer)
+ __hwasan_handle_vfork(sp);
+#endif // __has_feature(hwaddress_sanitizer)
+}
diff --git a/libc/bionic/heap_tagging.h b/libc/bionic/heap_tagging.h
index 110b6ed..5bc1da0 100644
--- a/libc/bionic/heap_tagging.h
+++ b/libc/bionic/heap_tagging.h
@@ -40,7 +40,22 @@
// useful for RAII on this lock.
extern pthread_mutex_t g_heap_tagging_lock;
-// These functions can be called in a multithreaded context, and thus should
+// This function can be called in a multithreaded context, and thus should
// only be called when holding the `g_heap_tagging_lock`.
bool SetHeapTaggingLevel(HeapTaggingLevel level);
-HeapTaggingLevel GetHeapTaggingLevel();
+
+// This is static because libc_nomalloc uses this but does not need to link the
+// cpp file.
+__attribute__((unused)) static inline const char* DescribeTaggingLevel(
+ HeapTaggingLevel level) {
+ switch (level) {
+ case M_HEAP_TAGGING_LEVEL_NONE:
+ return "none";
+ case M_HEAP_TAGGING_LEVEL_TBI:
+ return "tbi";
+ case M_HEAP_TAGGING_LEVEL_ASYNC:
+ return "async";
+ case M_HEAP_TAGGING_LEVEL_SYNC:
+ return "sync";
+ }
+}
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 8084e73..5d5ecac 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -27,11 +27,12 @@
*/
#include "libc_init_common.h"
-#include "heap_tagging.h"
+#include <async_safe/log.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -42,8 +43,8 @@
#include <sys/time.h>
#include <unistd.h>
-#include <async_safe/log.h>
-
+#include "heap_tagging.h"
+#include "private/ScopedPthreadMutexLocker.h"
#include "private/WriteProtected.h"
#include "private/bionic_defs.h"
#include "private/bionic_globals.h"
@@ -104,6 +105,51 @@
}
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+__attribute__((no_sanitize("hwaddress", "memtag"))) void
+__libc_init_mte_late() {
+#if defined(__aarch64__)
+ if (!__libc_shared_globals()->heap_tagging_upgrade_timer_sec) {
+ return;
+ }
+ struct sigevent event = {};
+ static timer_t timer;
+ event.sigev_notify = SIGEV_THREAD;
+ event.sigev_notify_function = [](union sigval) {
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "Downgrading MTE to async.");
+ ScopedPthreadMutexLocker l(&g_heap_tagging_lock);
+ SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC);
+ timer_delete(timer);
+ };
+
+ if (timer_create(CLOCK_REALTIME, &event, &timer) == -1) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "Failed to create MTE downgrade timer: %m");
+ // Revert back to ASYNC. If we fail to create or arm the timer, otherwise
+ // the process would be indefinitely stuck in SYNC.
+ SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC);
+ return;
+ }
+
+ struct itimerspec timerspec = {};
+ timerspec.it_value.tv_sec =
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec;
+ if (timer_settime(timer, /* flags= */ 0, &timerspec, nullptr) == -1) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "Failed to arm MTE downgrade timer: %m");
+ // Revert back to ASYNC. If we fail to create or arm the timer, otherwise
+ // the process would be indefinitely stuck in SYNC.
+ SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC);
+ timer_delete(timer);
+ return;
+ }
+ async_safe_format_log(
+ ANDROID_LOG_INFO, "libc", "Armed MTE downgrade timer for %" PRId64 " s",
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec);
+#endif
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
void __libc_add_main_thread() {
// Get the main thread from TLS and add it to the thread list.
pthread_internal_t* main_thread = __get_thread();
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 15c747e..6b39d6d 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -60,6 +60,8 @@
__LIBC_HIDDEN__ void __libc_init_scudo();
+__LIBC_HIDDEN__ void __libc_init_mte_late();
+
__LIBC_HIDDEN__ void __libc_init_AT_SECURE(char** envp);
// The fork handler must be initialised after __libc_init_malloc, as
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 24efbf5..c61810e 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -154,6 +154,8 @@
__cxa_atexit(__libc_fini,structors->fini_array,nullptr);
}
+ __libc_init_mte_late();
+
exit(slingshot(args.argc - __libc_shared_globals()->initial_linker_arg_count,
args.argv + __libc_shared_globals()->initial_linker_arg_count,
args.envp));
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 575da62..d64d402 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -29,6 +29,7 @@
#include <android/api-level.h>
#include <elf.h>
#include <errno.h>
+#include <malloc.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -36,10 +37,9 @@
#include <sys/auxv.h>
#include <sys/mman.h>
+#include "async_safe/log.h"
+#include "heap_tagging.h"
#include "libc_init_common.h"
-#include "pthread_internal.h"
-#include "sysprop_helpers.h"
-
#include "platform/bionic/macros.h"
#include "platform/bionic/mte.h"
#include "platform/bionic/page.h"
@@ -51,7 +51,9 @@
#include "private/bionic_elf_tls.h"
#include "private/bionic_globals.h"
#include "private/bionic_tls.h"
+#include "pthread_internal.h"
#include "sys/system_properties.h"
+#include "sysprop_helpers.h"
#if __has_feature(hwaddress_sanitizer)
#include <sanitizer/hwasan_interface.h>
@@ -74,33 +76,12 @@
}
}
-#if defined(__aarch64__) || defined(__x86_64__)
-extern __LIBC_HIDDEN__ __attribute__((weak)) ElfW(Rela) __rela_iplt_start[], __rela_iplt_end[];
-
-static void call_ifunc_resolvers() {
- if (__rela_iplt_start == nullptr || __rela_iplt_end == nullptr) {
- // These symbols are not emitted by gold. Gold has code to do so, but for
- // whatever reason it is not being run. In these cases ifuncs cannot be
- // resolved, so we do not support using ifuncs in static executables linked
- // with gold.
- //
- // Since they are weak, they will be non-null when linked with bfd/lld and
- // null when linked with gold.
- return;
- }
-
- for (ElfW(Rela) *r = __rela_iplt_start; r != __rela_iplt_end; ++r) {
- ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
- ElfW(Addr) resolver = r->r_addend;
- *offset = __bionic_call_ifunc_resolver(resolver);
- }
-}
-#else
+#if defined(__arm__) || defined(__i386__) // Legacy architectures used REL...
extern __LIBC_HIDDEN__ __attribute__((weak)) ElfW(Rel) __rel_iplt_start[], __rel_iplt_end[];
static void call_ifunc_resolvers() {
if (__rel_iplt_start == nullptr || __rel_iplt_end == nullptr) {
- // These symbols are not emitted by gold. Gold has code to do so, but for
+ // These symbols were not emitted by gold. Gold has code to do so, but for
// whatever reason it is not being run. In these cases ifuncs cannot be
// resolved, so we do not support using ifuncs in static executables linked
// with gold.
@@ -110,12 +91,33 @@
return;
}
- for (ElfW(Rel) *r = __rel_iplt_start; r != __rel_iplt_end; ++r) {
+ for (ElfW(Rel)* r = __rel_iplt_start; r != __rel_iplt_end; ++r) {
ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
ElfW(Addr) resolver = *offset;
*offset = __bionic_call_ifunc_resolver(resolver);
}
}
+#else // ...but modern architectures use RELA instead.
+extern __LIBC_HIDDEN__ __attribute__((weak)) ElfW(Rela) __rela_iplt_start[], __rela_iplt_end[];
+
+static void call_ifunc_resolvers() {
+ if (__rela_iplt_start == nullptr || __rela_iplt_end == nullptr) {
+ // These symbols were not emitted by gold. Gold has code to do so, but for
+ // whatever reason it is not being run. In these cases ifuncs cannot be
+ // resolved, so we do not support using ifuncs in static executables linked
+ // with gold.
+ //
+ // Since they are weak, they will be non-null when linked with bfd/lld and
+ // null when linked with gold.
+ return;
+ }
+
+ for (ElfW(Rela)* r = __rela_iplt_start; r != __rela_iplt_end; ++r) {
+ ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
+ ElfW(Addr) resolver = r->r_addend;
+ *offset = __bionic_call_ifunc_resolver(resolver);
+ }
+}
#endif
static void apply_gnu_relro() {
@@ -218,23 +220,25 @@
static bool get_environment_memtag_setting(HeapTaggingLevel* level) {
static const char kMemtagPrognameSyspropPrefix[] = "arm64.memtag.process.";
static const char kMemtagGlobalSysprop[] = "persist.arm64.memtag.default";
+ static const char kMemtagOverrideSyspropPrefix[] =
+ "persist.device_config.memory_safety_native.mode_override.process.";
const char* progname = __libc_shared_globals()->init_progname;
if (progname == nullptr) return false;
const char* basename = __gnu_basename(progname);
- static constexpr size_t kOptionsSize = PROP_VALUE_MAX;
- char options_str[kOptionsSize];
- size_t sysprop_size = strlen(basename) + strlen(kMemtagPrognameSyspropPrefix) + 1;
- char* sysprop_name = static_cast<char*>(alloca(sysprop_size));
-
- async_safe_format_buffer(sysprop_name, sysprop_size, "%s%s", kMemtagPrognameSyspropPrefix,
+ char options_str[PROP_VALUE_MAX];
+ char sysprop_name[512];
+ async_safe_format_buffer(sysprop_name, sizeof(sysprop_name), "%s%s", kMemtagPrognameSyspropPrefix,
basename);
- const char* sys_prop_names[] = {sysprop_name, kMemtagGlobalSysprop};
+ char remote_sysprop_name[512];
+ async_safe_format_buffer(remote_sysprop_name, sizeof(remote_sysprop_name), "%s%s",
+ kMemtagOverrideSyspropPrefix, basename);
+ const char* sys_prop_names[] = {sysprop_name, remote_sysprop_name, kMemtagGlobalSysprop};
if (!get_config_from_env_or_sysprops("MEMTAG_OPTIONS", sys_prop_names, arraysize(sys_prop_names),
- options_str, kOptionsSize)) {
+ options_str, sizeof(options_str))) {
return false;
}
@@ -259,17 +263,18 @@
// M_HEAP_TAGGING_LEVEL_NONE, if MTE isn't enabled for this process we enable
// M_HEAP_TAGGING_LEVEL_TBI.
static HeapTaggingLevel __get_heap_tagging_level(const void* phdr_start, size_t phdr_ct,
- uintptr_t load_bias) {
+ uintptr_t load_bias, bool* stack) {
+ unsigned note_val =
+ __get_memtag_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct, load_bias);
+ *stack = note_val & NT_MEMTAG_STACK;
+
HeapTaggingLevel level;
if (get_environment_memtag_setting(&level)) return level;
- unsigned note_val =
- __get_memtag_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct, load_bias);
-
// Note, previously (in Android 12), any value outside of bits [0..3] resulted
// in a check-fail. In order to be permissive of further extensions, we
- // relaxed this restriction. For now, we still only support MTE heap.
- if (!(note_val & NT_MEMTAG_HEAP)) return M_HEAP_TAGGING_LEVEL_TBI;
+ // relaxed this restriction.
+ if (!(note_val & (NT_MEMTAG_HEAP | NT_MEMTAG_STACK))) return M_HEAP_TAGGING_LEVEL_TBI;
unsigned mode = note_val & NT_MEMTAG_LEVEL_MASK;
switch (mode) {
@@ -295,9 +300,47 @@
// This function is called from the linker before the main executable is relocated.
__attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(const void* phdr_start,
size_t phdr_ct,
- uintptr_t load_bias) {
- HeapTaggingLevel level = __get_heap_tagging_level(phdr_start, phdr_ct, load_bias);
-
+ uintptr_t load_bias,
+ void* stack_top) {
+ bool memtag_stack;
+ HeapTaggingLevel level = __get_heap_tagging_level(phdr_start, phdr_ct, load_bias, &memtag_stack);
+ char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS");
+ static const char kAppProcessName[] = "app_process64";
+ const char* progname = __libc_shared_globals()->init_progname;
+ progname = progname ? __gnu_basename(progname) : nullptr;
+ if (progname &&
+ strncmp(progname, kAppProcessName, sizeof(kAppProcessName)) == 0) {
+ // disable timed upgrade for zygote, as the thread spawned will violate the requirement
+ // that it be single-threaded.
+ env = nullptr;
+ }
+ int64_t timed_upgrade = 0;
+ if (env) {
+ char* endptr;
+ timed_upgrade = strtoll(env, &endptr, 10);
+ if (*endptr != '\0' || timed_upgrade < 0) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "Invalid value for BIONIC_MEMTAG_UPGRADE_SECS: %s",
+ env);
+ timed_upgrade = 0;
+ }
+ // Make sure that this does not get passed to potential processes inheriting
+ // this environment.
+ unsetenv("BIONIC_MEMTAG_UPGRADE_SECS");
+ }
+ if (timed_upgrade) {
+ if (level == M_HEAP_TAGGING_LEVEL_ASYNC) {
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "Attempting timed MTE upgrade from async to sync.");
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec = timed_upgrade;
+ level = M_HEAP_TAGGING_LEVEL_SYNC;
+ } else if (level != M_HEAP_TAGGING_LEVEL_SYNC) {
+ async_safe_format_log(
+ ANDROID_LOG_ERROR, "libc",
+ "Requested timed MTE upgrade from invalid %s to sync. Ignoring.",
+ DescribeTaggingLevel(level));
+ }
+ }
if (level == M_HEAP_TAGGING_LEVEL_SYNC || level == M_HEAP_TAGGING_LEVEL_ASYNC) {
unsigned long prctl_arg = PR_TAGGED_ADDR_ENABLE | PR_MTE_TAG_SET_NONZERO;
prctl_arg |= (level == M_HEAP_TAGGING_LEVEL_SYNC) ? PR_MTE_TCF_SYNC : PR_MTE_TCF_ASYNC;
@@ -308,6 +351,17 @@
if (prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg | PR_MTE_TCF_SYNC, 0, 0, 0) == 0 ||
prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg, 0, 0, 0) == 0) {
__libc_shared_globals()->initial_heap_tagging_level = level;
+ __libc_shared_globals()->initial_memtag_stack = memtag_stack;
+
+ if (memtag_stack) {
+ void* page_start =
+ reinterpret_cast<void*>(PAGE_START(reinterpret_cast<uintptr_t>(stack_top)));
+ if (mprotect(page_start, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
+ async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %s\n",
+ strerror(errno));
+ }
+ }
+
return;
}
}
@@ -317,9 +371,11 @@
if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) {
__libc_shared_globals()->initial_heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI;
}
+ // We did not enable MTE, so we do not need to arm the upgrade timer.
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec = 0;
}
#else // __aarch64__
-void __libc_init_mte(const void*, size_t, uintptr_t) {}
+void __libc_init_mte(const void*, size_t, uintptr_t, void*) {}
#endif // __aarch64__
void __libc_init_profiling_handlers() {
@@ -331,11 +387,9 @@
signal(BIONIC_SIGNAL_ART_PROFILER, SIG_IGN);
}
-__noreturn static void __real_libc_init(void *raw_args,
- void (*onexit)(void) __unused,
- int (*slingshot)(int, char**, char**),
- structors_array_t const * const structors,
- bionic_tcb* temp_tcb) {
+__attribute__((no_sanitize("memtag"))) __noreturn static void __real_libc_init(
+ void* raw_args, void (*onexit)(void) __unused, int (*slingshot)(int, char**, char**),
+ structors_array_t const* const structors, bionic_tcb* temp_tcb) {
BIONIC_STOP_UNWIND;
// Initialize TLS early so system calls and errno work.
@@ -349,7 +403,7 @@
__libc_init_main_thread_final();
__libc_init_common();
__libc_init_mte(reinterpret_cast<ElfW(Phdr)*>(getauxval(AT_PHDR)), getauxval(AT_PHNUM),
- /*load_bias = */ 0);
+ /*load_bias = */ 0, /*stack_top = */ raw_args);
__libc_init_scudo();
__libc_init_profiling_handlers();
__libc_init_fork_handler();
@@ -370,6 +424,8 @@
__cxa_atexit(__libc_fini,structors->fini_array,nullptr);
}
+ __libc_init_mte_late();
+
exit(slingshot(args.argc, args.argv, args.envp));
}
@@ -379,11 +435,9 @@
//
// The 'structors' parameter contains pointers to various initializer
// arrays that must be run before the program's 'main' routine is launched.
-__attribute__((no_sanitize("hwaddress")))
-__noreturn void __libc_init(void* raw_args,
- void (*onexit)(void) __unused,
- int (*slingshot)(int, char**, char**),
- structors_array_t const * const structors) {
+__attribute__((no_sanitize("hwaddress", "memtag"))) __noreturn void __libc_init(
+ void* raw_args, void (*onexit)(void) __unused, int (*slingshot)(int, char**, char**),
+ structors_array_t const* const structors) {
bionic_tcb temp_tcb = {};
#if __has_feature(hwaddress_sanitizer)
// Install main thread TLS early. It will be initialized later in __libc_init_main_thread. For now
diff --git a/libc/bionic/locale.cpp b/libc/bionic/locale.cpp
index 0b7037a..2f4d206 100644
--- a/libc/bionic/locale.cpp
+++ b/libc/bionic/locale.cpp
@@ -54,23 +54,23 @@
struct __locale_t {
size_t mb_cur_max;
-
- explicit __locale_t(size_t mb_cur_max) : mb_cur_max(mb_cur_max) {
- }
-
- explicit __locale_t(const __locale_t* other) {
- if (other == LC_GLOBAL_LOCALE) {
- mb_cur_max = __bionic_current_locale_is_utf8 ? 4 : 1;
- } else {
- mb_cur_max = other->mb_cur_max;
- }
- }
-
- BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(__locale_t);
};
-size_t __ctype_get_mb_cur_max() {
- locale_t l = uselocale(nullptr);
+// Avoid using new/delete in this file, because a user may have overridden
+// new/delete, and we want to avoid making extraneous calls to them. This isn't
+// an issue for libc.so in the platform, but this file is also compiled into the
+// NDK's libandroid_support.a, and there are libc++ tests that count the number
+// of calls to new/delete.
+#pragma clang poison new delete
+
+static inline locale_t __alloc_locale(size_t mb_cur_max) {
+ auto result = static_cast<__locale_t*>(malloc(sizeof(__locale_t)));
+ if (result == nullptr) return nullptr;
+ result->mb_cur_max = mb_cur_max;
+ return result;
+}
+
+static inline size_t get_locale_mb_cur_max(locale_t l) {
if (l == LC_GLOBAL_LOCALE) {
return __bionic_current_locale_is_utf8 ? 4 : 1;
} else {
@@ -78,6 +78,10 @@
}
}
+size_t __ctype_get_mb_cur_max() {
+ return get_locale_mb_cur_max(uselocale(nullptr));
+}
+
#if !USE_TLS_SLOT
static thread_local locale_t g_current_locale;
#endif
@@ -133,11 +137,11 @@
}
locale_t duplocale(locale_t l) {
- return new __locale_t(l);
+ return __alloc_locale(get_locale_mb_cur_max(l));
}
void freelocale(locale_t l) {
- delete l;
+ free(l);
}
locale_t newlocale(int category_mask, const char* locale_name, locale_t /*base*/) {
@@ -152,7 +156,7 @@
return nullptr;
}
- return new __locale_t(__is_utf8_locale(locale_name) ? 4 : 1);
+ return __alloc_locale(__is_utf8_locale(locale_name) ? 4 : 1);
}
char* setlocale(int category, const char* locale_name) {
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 9744968..e159fdc 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -333,6 +333,14 @@
return EnableGwpAsan(*reinterpret_cast<android_mallopt_gwp_asan_options_t*>(arg));
}
+ if (opcode == M_MEMTAG_STACK_IS_ON) {
+ if (arg == nullptr || arg_size != sizeof(bool)) {
+ errno = EINVAL;
+ return false;
+ }
+ *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_globals->memtag_stack);
+ return true;
+ }
errno = ENOTSUP;
return false;
}
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index 6c2f4d9..97e8d15 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -533,6 +533,14 @@
return EnableGwpAsan(*reinterpret_cast<android_mallopt_gwp_asan_options_t*>(arg));
}
+ if (opcode == M_MEMTAG_STACK_IS_ON) {
+ if (arg == nullptr || arg_size != sizeof(bool)) {
+ errno = EINVAL;
+ return false;
+ }
+ *reinterpret_cast<bool*>(arg) = atomic_load(&__libc_globals->memtag_stack);
+ return true;
+ }
// Try heapprofd's mallopt, as it handles options not covered here.
return HeapprofdMallopt(opcode, arg, arg_size);
}
diff --git a/libc/bionic/memset_explicit.cpp b/libc/bionic/memset_explicit.cpp
new file mode 100644
index 0000000..2bcc20c
--- /dev/null
+++ b/libc/bionic/memset_explicit.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+void* memset_explicit(void* __dst, int __ch, size_t __n) {
+ void* result = memset(__dst, __ch, __n);
+ // https://bugs.llvm.org/show_bug.cgi?id=15495
+ __asm__ __volatile__("" : : "r"(__dst) : "memory");
+ return result;
+}
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
index 9aad0b3..ed6b9c6 100644
--- a/libc/bionic/mmap.cpp
+++ b/libc/bionic/mmap.cpp
@@ -39,37 +39,20 @@
#define MMAP2_SHIFT 12 // 2**12 == 4096
-static bool kernel_has_MADV_MERGEABLE = true;
-
void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
if (offset < 0 || (offset & ((1UL << MMAP2_SHIFT)-1)) != 0) {
errno = EINVAL;
return MAP_FAILED;
}
- // prevent allocations large enough for `end - start` to overflow
+ // Prevent allocations large enough for `end - start` to overflow.
size_t rounded = __BIONIC_ALIGN(size, PAGE_SIZE);
if (rounded < size || rounded > PTRDIFF_MAX) {
errno = ENOMEM;
return MAP_FAILED;
}
- bool is_private_anonymous =
- (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) == (MAP_PRIVATE | MAP_ANONYMOUS);
- bool is_stack_or_grows_down = (flags & (MAP_STACK | MAP_GROWSDOWN)) != 0;
-
- void* result = __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
-
- if (result != MAP_FAILED && kernel_has_MADV_MERGEABLE &&
- is_private_anonymous && !is_stack_or_grows_down) {
- ErrnoRestorer errno_restorer;
- int rc = madvise(result, size, MADV_MERGEABLE);
- if (rc == -1 && errno == EINVAL) {
- kernel_has_MADV_MERGEABLE = false;
- }
- }
-
- return result;
+ return __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
}
void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 121b26f..417ce76 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -40,15 +40,16 @@
#include <async_safe/log.h>
+#include "platform/bionic/macros.h"
+#include "platform/bionic/mte.h"
+#include "private/ErrnoRestorer.h"
#include "private/ScopedRWLock.h"
#include "private/bionic_constants.h"
#include "private/bionic_defs.h"
#include "private/bionic_globals.h"
-#include "platform/bionic/macros.h"
#include "private/bionic_ssp.h"
#include "private/bionic_systrace.h"
#include "private/bionic_tls.h"
-#include "private/ErrnoRestorer.h"
// x86 uses segment descriptors rather than a direct pointer to TLS.
#if defined(__i386__)
@@ -88,7 +89,13 @@
static void __init_alternate_signal_stack(pthread_internal_t* thread) {
// Create and set an alternate signal stack.
- void* stack_base = mmap(nullptr, SIGNAL_STACK_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ int prot = PROT_READ | PROT_WRITE;
+#ifdef __aarch64__
+ if (atomic_load(&__libc_globals->memtag_stack)) {
+ prot |= PROT_MTE;
+ }
+#endif
+ void* stack_base = mmap(nullptr, SIGNAL_STACK_SIZE, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (stack_base != MAP_FAILED) {
// Create a guard to catch stack overflows in signal handlers.
if (mprotect(stack_base, PTHREAD_GUARD_SIZE, PROT_NONE) == -1) {
@@ -224,12 +231,19 @@
return {};
}
const size_t writable_size = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE;
- if (mprotect(space + stack_guard_size,
- writable_size,
- PROT_READ | PROT_WRITE) != 0) {
- async_safe_format_log(ANDROID_LOG_WARN, "libc",
- "pthread_create failed: couldn't mprotect R+W %zu-byte thread mapping region: %s",
- writable_size, strerror(errno));
+ int prot = PROT_READ | PROT_WRITE;
+ const char* prot_str = "R+W";
+#ifdef __aarch64__
+ if (atomic_load(&__libc_globals->memtag_stack)) {
+ prot |= PROT_MTE;
+ prot_str = "R+W+MTE";
+ }
+#endif
+ if (mprotect(space + stack_guard_size, writable_size, prot) != 0) {
+ async_safe_format_log(
+ ANDROID_LOG_WARN, "libc",
+ "pthread_create failed: couldn't mprotect %s %zu-byte thread mapping region: %s", prot_str,
+ writable_size, strerror(errno));
munmap(space, mmap_size);
return {};
}
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 071a5bc..7222b62 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -160,6 +160,13 @@
bionic_tls* bionic_tls;
int errno_value;
+
+ // The last observed value of SP in a vfork child process.
+ // The part of the stack between this address and the value of SP when the vfork parent process
+ // regains control may have stale MTE tags and needs cleanup. This field is only meaningful while
+ // the parent is waiting for the vfork child to return control by calling either exec*() or
+ // exit().
+ void* vfork_child_stack_bottom;
};
struct ThreadMapping {
diff --git a/libc/bionic/rename.cpp b/libc/bionic/rename.cpp
index 8295559..89786f7 100644
--- a/libc/bionic/rename.cpp
+++ b/libc/bionic/rename.cpp
@@ -30,5 +30,9 @@
#include <stdio.h>
int rename(const char* old_path, const char* new_path) {
- return renameat(AT_FDCWD, old_path, AT_FDCWD, new_path);
+ return renameat2(AT_FDCWD, old_path, AT_FDCWD, new_path, 0);
+}
+
+int renameat(int old_dir_fd, const char* old_path, int new_dir_fd, const char* new_path) {
+ return renameat2(old_dir_fd, old_path, new_dir_fd, new_path, 0);
}
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 59f7631..7e80ef6 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -52,7 +52,7 @@
// mark all open fds except stdin/out/err as close-on-exec
static int cloexec_except_stdioe() {
// requires 5.11+ or ACK 5.10-T kernel, otherwise returns ENOSYS or EINVAL
- if (!syscall(SYS_close_range, 3, ~0U, CLOSE_RANGE_CLOEXEC)) return 0;
+ if (!close_range(3, ~0U, CLOSE_RANGE_CLOEXEC)) return 0;
// unfortunately getrlimit can lie:
// - both soft and hard limits can be lowered to 0, with fds still open, so it can underestimate
diff --git a/libc/bionic/strtol.cpp b/libc/bionic/strtol.cpp
index 77f1d92..ec72b09 100644
--- a/libc/bionic/strtol.cpp
+++ b/libc/bionic/strtol.cpp
@@ -32,11 +32,13 @@
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>
+#include <wchar.h>
-template <typename T, T Min, T Max> T StrToI(const char* nptr, char** endptr, int base) {
+template <typename T, T Min, T Max, typename CharT>
+T StrToI(const CharT* nptr, CharT** endptr, int base) {
// Ensure that base is between 2 and 36 inclusive, or the special value of 0.
if (base < 0 || base == 1 || base > 36) {
- if (endptr != nullptr) *endptr = const_cast<char*>(nptr);
+ if (endptr != nullptr) *endptr = const_cast<CharT*>(nptr);
errno = EINVAL;
return 0;
}
@@ -44,7 +46,7 @@
// Skip white space and pick up leading +/- sign if any.
// If base is 0, allow 0x for hex and 0 for octal, else
// assume decimal; if base is already 16, allow 0x.
- const char* s = nptr;
+ const CharT* s = nptr;
int c;
do {
c = *s++;
@@ -62,6 +64,11 @@
s += 2;
base = 16;
}
+ if ((base == 0 || base == 2) && c == '0' && (*s == 'b' || *s == 'B') && isdigit(s[1])) {
+ c = s[1];
+ s += 2;
+ base = 2;
+ }
if (base == 0) base = (c == '0') ? 8 : 10;
// We always work in the negative space because the most negative value has a
@@ -91,7 +98,7 @@
acc -= c;
}
}
- if (endptr != nullptr) *endptr = const_cast<char*>(any ? s - 1 : nptr);
+ if (endptr != nullptr) *endptr = const_cast<CharT*>(any ? s - 1 : nptr);
if (!neg) {
if (acc == Min) {
errno = ERANGE;
@@ -103,14 +110,15 @@
return acc;
}
-template <typename T, T Max> T StrToU(const char* nptr, char** endptr, int base) {
+template <typename T, T Max, typename CharT>
+T StrToU(const CharT* nptr, CharT** endptr, int base) {
if (base < 0 || base == 1 || base > 36) {
- if (endptr != nullptr) *endptr = const_cast<char*>(nptr);
+ if (endptr != nullptr) *endptr = const_cast<CharT*>(nptr);
errno = EINVAL;
return 0;
}
- const char* s = nptr;
+ const CharT* s = nptr;
int c;
do {
c = *s++;
@@ -128,6 +136,11 @@
s += 2;
base = 16;
}
+ if ((base == 0 || base == 2) && c == '0' && (*s == 'b' || *s == 'B') && isdigit(s[1])) {
+ c = s[1];
+ s += 2;
+ base = 2;
+ }
if (base == 0) base = (c == '0') ? 8 : 10;
T cutoff = Max / static_cast<T>(base);
@@ -155,7 +168,7 @@
}
}
if (neg && any > 0) acc = -acc;
- if (endptr != nullptr) *endptr = const_cast<char*>(any ? s - 1 : nptr);
+ if (endptr != nullptr) *endptr = const_cast<CharT*>(any ? s - 1 : nptr);
return acc;
}
@@ -172,30 +185,54 @@
}
intmax_t strtoimax(const char* s, char** end, int base) {
- return StrToI<intmax_t, INTMAX_MIN, INTMAX_MAX>(s, end, base);
+ return StrToI<intmax_t, INTMAX_MIN, INTMAX_MAX, char>(s, end, base);
+}
+
+intmax_t wcstoimax(const wchar_t* s, wchar_t** end, int base) {
+ return StrToI<intmax_t, INTMAX_MIN, INTMAX_MAX, wchar_t>(s, end, base);
}
long strtol(const char* s, char** end, int base) {
- return StrToI<long, LONG_MIN, LONG_MAX>(s, end, base);
+ return StrToI<long, LONG_MIN, LONG_MAX, char>(s, end, base);
+}
+
+long wcstol(const wchar_t* s, wchar_t** end, int base) {
+ return StrToI<long, LONG_MIN, LONG_MAX, wchar_t>(s, end, base);
}
long long strtoll(const char* s, char** end, int base) {
- return StrToI<long long, LLONG_MIN, LLONG_MAX>(s, end, base);
+ return StrToI<long long, LLONG_MIN, LLONG_MAX, char>(s, end, base);
+}
+
+long long wcstoll(const wchar_t* s, wchar_t** end, int base) {
+ return StrToI<long long, LLONG_MIN, LLONG_MAX, wchar_t>(s, end, base);
}
// Public API since L, but not in any header.
__strong_alias(strtoq, strtoll);
unsigned long strtoul(const char* s, char** end, int base) {
- return StrToU<unsigned long, ULONG_MAX>(s, end, base);
+ return StrToU<unsigned long, ULONG_MAX, char>(s, end, base);
+}
+
+unsigned long wcstoul(const wchar_t* s, wchar_t** end, int base) {
+ return StrToU<unsigned long, ULONG_MAX, wchar_t>(s, end, base);
}
unsigned long long strtoull(const char* s, char** end, int base) {
- return StrToU<unsigned long long, ULLONG_MAX>(s, end, base);
+ return StrToU<unsigned long long, ULLONG_MAX, char>(s, end, base);
+}
+
+unsigned long long wcstoull(const wchar_t* s, wchar_t** end, int base) {
+ return StrToU<unsigned long long, ULLONG_MAX, wchar_t>(s, end, base);
}
uintmax_t strtoumax(const char* s, char** end, int base) {
- return StrToU<uintmax_t, UINTMAX_MAX>(s, end, base);
+ return StrToU<uintmax_t, UINTMAX_MAX, char>(s, end, base);
+}
+
+uintmax_t wcstoumax(const wchar_t* s, wchar_t** end, int base) {
+ return StrToU<uintmax_t, UINTMAX_MAX, wchar_t>(s, end, base);
}
// Public API since L, but not in any header.
diff --git a/libc/bionic/sysinfo.cpp b/libc/bionic/sysinfo.cpp
index 7ab8e9e..1e4a0e8 100644
--- a/libc/bionic/sysinfo.cpp
+++ b/libc/bionic/sysinfo.cpp
@@ -36,47 +36,31 @@
#include "private/get_cpu_count_from_string.h"
#include "private/ScopedReaddir.h"
-static bool __matches_cpuN(const char* s) {
- // The %c trick is to ensure that we have the anchored match "^cpu[0-9]+$".
- // We can't use %*c because the return value is how many were *assigned*.
- unsigned cpu;
- char unused;
- return (sscanf(s, "cpu%u%c", &cpu, &unused) == 1);
-}
-
-int get_nprocs_conf() {
- // On x86 kernels you can use /proc/cpuinfo for this, but on ARM kernels offline CPUs disappear
- // from there. This method works on both.
- ScopedReaddir reader("/sys/devices/system/cpu");
- if (reader.IsBad()) {
- return 1;
- }
-
- int result = 0;
- dirent* entry;
- while ((entry = reader.ReadEntry()) != nullptr) {
- if (entry->d_type == DT_DIR && __matches_cpuN(entry->d_name)) {
- ++result;
- }
- }
- return result;
-}
-
-int get_nprocs() {
+int __get_cpu_count(const char* sys_file) {
int cpu_count = 1;
- FILE* fp = fopen("/sys/devices/system/cpu/online", "re");
+ FILE* fp = fopen(sys_file, "re");
if (fp != nullptr) {
char* line = nullptr;
- size_t len = 0;
- if (getline(&line, &len, fp) != -1) {
+ size_t allocated_size = 0;
+ if (getline(&line, &allocated_size, fp) != -1) {
cpu_count = GetCpuCountFromString(line);
- free(line);
}
+ free(line);
fclose(fp);
}
return cpu_count;
}
+int get_nprocs_conf() {
+ // It's unclear to me whether this is intended to be "possible" or "present",
+ // but on mobile they're unlikely to differ.
+ return __get_cpu_count("/sys/devices/system/cpu/possible");
+}
+
+int get_nprocs() {
+ return __get_cpu_count("/sys/devices/system/cpu/online");
+}
+
long get_phys_pages() {
struct sysinfo si;
sysinfo(&si);
diff --git a/libc/bionic/sysprop_helpers.cpp b/libc/bionic/sysprop_helpers.cpp
index edae6cc..5627034 100644
--- a/libc/bionic/sysprop_helpers.cpp
+++ b/libc/bionic/sysprop_helpers.cpp
@@ -53,9 +53,7 @@
strncpy(cb_cookie->dest, value, cb_cookie->size);
},
&cb_cookie);
- if (*dest != '\0' && *dest != '0') return true;
-
- return false;
+ return *dest != '\0';
}
bool get_config_from_env_or_sysprops(const char* env_var_name, const char* const* sys_prop_names,
diff --git a/libc/bionic/time64.c b/libc/bionic/time64.c
index da38bf3..73f24ab 100644
--- a/libc/bionic/time64.c
+++ b/libc/bionic/time64.c
@@ -483,6 +483,11 @@
}
+/* This implementation violates mktime specification, according to which
+ tm_yday, tm_wday, and tm_isdst fields should be updated. This function
+ leaves input_date unmodified. Given that there were no bug reports, fixing
+ it might cause more troubles than just leaving it as it is.
+ */
Time64_T mktime64(const struct TM *input_date) {
struct tm safe_date;
struct TM date;
diff --git a/libc/dns/resolv/res_send.c b/libc/dns/resolv/res_send.c
index fa81e6d..a95997d 100644
--- a/libc/dns/resolv/res_send.c
+++ b/libc/dns/resolv/res_send.c
@@ -680,8 +680,7 @@
/* Private */
static int
-get_salen(sa)
- const struct sockaddr *sa;
+get_salen(const struct sockaddr *sa)
{
#ifdef HAVE_SA_LEN
@@ -702,9 +701,7 @@
* pick appropriate nsaddr_list for use. see res_init() for initialization.
*/
static struct sockaddr *
-get_nsaddr(statp, n)
- res_state statp;
- size_t n;
+get_nsaddr(res_state statp, size_t n)
{
if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) {
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index ecf318d..79085d1 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -139,21 +139,32 @@
#define __ANDROID_API_P__ 28
/**
- * Names the "Q" API level (29), for comparison against `__ANDROID_API__`.
- * This release was called Android 10 publicly, not to be (but sure to be)
- * confused with API level 10.
+ * Names the Android 10 (aka "Q" or "Quince Tart") API level (29), for
+ * comparison against `__ANDROID_API__`.
*/
#define __ANDROID_API_Q__ 29
-/** Names the "R" API level (30), for comparison against `__ANDROID_API__`. */
+/**
+ * Names the Android 11 (aka "R" or "Red Velvet Cake") API level (30), for
+ * comparison against `__ANDROID_API__`.
+ */
#define __ANDROID_API_R__ 30
-/** Names the "S" API level (31), for comparison against `__ANDROID_API__`. */
+/**
+ * Names the Android 12 (aka "S" or "Snowcone") API level (31), for
+ * comparison against `__ANDROID_API__`.
+ */
#define __ANDROID_API_S__ 31
-/** Names the "T" API level (33), for comparison against `__ANDROID_API__`. */
+/**
+ * Names the Android 13 (aka "T" or "Tiramisu") API level (33), for
+ * comparison against `__ANDROID_API__`.
+ */
#define __ANDROID_API_T__ 33
+/** Names the "U" API level (34), for comparison against `__ANDROID_API__`. */
+#define __ANDROID_API_U__ 34
+
/* This file is included in <features.h>, and might be used from .S files. */
#if !defined(__ASSEMBLY__)
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index e23de85..59ce133 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -123,6 +123,9 @@
/* libziparchive's ZipArchive */
ANDROID_FDSAN_OWNER_TYPE_ZIPARCHIVE = 12,
+
+ /* native_handle_t */
+ ANDROID_FDSAN_OWNER_TYPE_NATIVE_HANDLE = 13,
};
/*
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index aeb1575..6903536 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -57,13 +57,11 @@
__BEGIN_DECLS
static __inline float strtof(const char* nptr, char** endptr) {
+ // N.B. Double-rounding makes this function incorrect for some inputs.
double d = strtod(nptr, endptr);
- if (d > FLT_MAX) {
+ if (__builtin_isfinite(d) && __builtin_fabs(d) > FLT_MAX) {
errno = ERANGE;
- return __builtin_huge_valf();
- } else if (d < -FLT_MAX) {
- errno = ERANGE;
- return -__builtin_huge_valf();
+ return __builtin_copysign(__builtin_huge_valf(), d);
}
return __BIONIC_CAST(static_cast, float, d);
}
diff --git a/libc/include/bits/elf_arm.h b/libc/include/bits/elf_arm.h
deleted file mode 100644
index 08fe1d5..0000000
--- a/libc/include/bits/elf_arm.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* $NetBSD: elf_machdep.h,v 1.17 2014/02/25 19:20:09 matt Exp $ */
-
-#ifndef _ARM_ELF_MACHDEP_H_
-#define _ARM_ELF_MACHDEP_H_
-
-/* Android-added. */
-#define R_ARM_IRELATIVE 160
-
-/* Processor specific flags for the ELF header e_flags field. */
-#define EF_ARM_RELEXEC 0x00000001
-#define EF_ARM_HASENTRY 0x00000002
-#define EF_ARM_INTERWORK 0x00000004 /* GNU binutils 000413 */
-#define EF_ARM_SYMSARESORTED 0x00000004 /* ARM ELF A08 */
-#define EF_ARM_APCS_26 0x00000008 /* GNU binutils 000413 */
-#define EF_ARM_DYNSYMSUSESEGIDX 0x00000008 /* ARM ELF B01 */
-#define EF_ARM_APCS_FLOAT 0x00000010 /* GNU binutils 000413 */
-#define EF_ARM_MAPSYMSFIRST 0x00000010 /* ARM ELF B01 */
-#define EF_ARM_PIC 0x00000020
-#define EF_ARM_ALIGN8 0x00000040 /* 8-bit structure alignment. */
-#define EF_ARM_NEW_ABI 0x00000080
-#define EF_ARM_OLD_ABI 0x00000100
-#define EF_ARM_SOFT_FLOAT 0x00000200
-#define EF_ARM_BE8 0x00800000
-#define EF_ARM_EABIMASK 0xff000000
-#define EF_ARM_EABI_VER1 0x01000000
-#define EF_ARM_EABI_VER2 0x02000000
-#define EF_ARM_EABI_VER3 0x03000000
-#define EF_ARM_EABI_VER4 0x04000000
-#define EF_ARM_EABI_VER5 0x05000000
-
-/* Processor specific relocation types */
-
-#define R_ARM_NONE 0
-#define R_ARM_PC24 1
-#define R_ARM_ABS32 2
-#define R_ARM_REL32 3
-#define R_ARM_PC13 4
-#define R_ARM_ABS16 5
-#define R_ARM_ABS12 6
-#define R_ARM_THM_ABS5 7
-#define R_ARM_ABS8 8
-#define R_ARM_SBREL32 9
-#define R_ARM_THM_PC22 10
-#define R_ARM_THM_PC8 11
-#define R_ARM_AMP_VCALL9 12
-#define R_ARM_SWI24 13 /* obsolete static relocation */
-#define R_ARM_TLS_DESC 13 /* dynamic relocation */
-#define R_ARM_THM_SWI8 14
-#define R_ARM_XPC25 15
-#define R_ARM_THM_XPC22 16
-
-/* TLS relocations */
-#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
-#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
-#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
-
-/* 20-31 are reserved for ARM Linux. */
-#define R_ARM_COPY 20
-#define R_ARM_GLOB_DAT 21
-#define R_ARM_JUMP_SLOT 22
-#define R_ARM_RELATIVE 23
-#define R_ARM_GOTOFF 24
-#define R_ARM_GOTPC 25
-#define R_ARM_GOT32 26
-#define R_ARM_PLT32 27
-#define R_ARM_CALL 28
-#define R_ARM_JUMP24 29
-#define R_ARM_THM_JUMP24 30
-#define R_ARM_BASE_ABS 31
-#define R_ARM_ALU_PCREL_7_0 32
-#define R_ARM_ALU_PCREL_15_8 33
-#define R_ARM_ALU_PCREL_23_15 34
-#define R_ARM_ALU_SBREL_11_0 35
-#define R_ARM_ALU_SBREL_19_12 36
-#define R_ARM_ALU_SBREL_27_20 37 // depcreated
-#define R_ARM_TARGET1 38
-#define R_ARM_SBREL31 39 // deprecated
-#define R_ARM_V4BX 40
-#define R_ARM_TARGET2 41
-#define R_ARM_PREL31 42
-#define R_ARM_MOVW_ABS_NC 43
-#define R_ARM_MOVT_ABS 44
-#define R_ARM_MOVW_PREL_NC 45
-#define R_ARM_MOVT_PREL 46
-#define R_ARM_THM_MOVW_ABS_NC 47
-#define R_ARM_THM_MOVT_ABS 48
-#define R_ARM_THM_MOVW_PREL_NC 49
-#define R_ARM_THM_MOVT_PREL 50
-
-/* 96-111 are reserved to G++. */
-#define R_ARM_GNU_VTENTRY 100
-#define R_ARM_GNU_VTINHERIT 101
-#define R_ARM_THM_PC11 102
-#define R_ARM_THM_PC9 103
-
-/* More TLS relocations */
-#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic */
-#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic */
-#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS */
-#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of */
-#define R_ARM_TLS_LE32 108
-#define R_ARM_TLS_LDO12 109
-#define R_ARM_TLS_LE12 110
-#define R_ARM_TLS_IE12GP 111
-
-/* 112-127 are reserved for private experiments. */
-
-#define R_ARM_RXPC25 249
-#define R_ARM_RSBREL32 250
-#define R_ARM_THM_RPC22 251
-#define R_ARM_RREL32 252
-#define R_ARM_RABS32 253
-#define R_ARM_RPC24 254
-#define R_ARM_RBASE 255
-
-/* Processor specific program header flags */
-#define PF_ARM_SB 0x10000000
-#define PF_ARM_PI 0x20000000
-#define PF_ARM_ENTRY 0x80000000
-
-/* Processor specific program header types */
-#define PT_ARM_EXIDX (PT_LOPROC + 1)
-
-/* Processor specific section header flags */
-#define SHF_ENTRYSECT 0x10000000
-#define SHF_COMDEF 0x80000000
-
-/* Processor specific symbol types */
-#define STT_ARM_TFUNC STT_LOPROC
-
-#endif /* _ARM_ELF_MACHDEP_H_ */
diff --git a/libc/include/bits/elf_arm64.h b/libc/include/bits/elf_arm64.h
deleted file mode 100644
index 9330d7b..0000000
--- a/libc/include/bits/elf_arm64.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2013 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 _AARCH64_ELF_MACHDEP_H_
-#define _AARCH64_ELF_MACHDEP_H_
-
-/* Null relocations */
-#define R_ARM_NONE 0
-#define R_AARCH64_NONE 256
-
-/* Static Data relocations */
-#define R_AARCH64_ABS64 257
-#define R_AARCH64_ABS32 258
-#define R_AARCH64_ABS16 259
-#define R_AARCH64_PREL64 260
-#define R_AARCH64_PREL32 261
-#define R_AARCH64_PREL16 262
-
-#define R_AARCH64_MOVW_UABS_G0 263
-#define R_AARCH64_MOVW_UABS_G0_NC 264
-#define R_AARCH64_MOVW_UABS_G1 265
-#define R_AARCH64_MOVW_UABS_G1_NC 266
-#define R_AARCH64_MOVW_UABS_G2 267
-#define R_AARCH64_MOVW_UABS_G2_NC 268
-#define R_AARCH64_MOVW_UABS_G3 269
-#define R_AARCH64_MOVW_SABS_G0 270
-#define R_AARCH64_MOVW_SABS_G1 271
-#define R_AARCH64_MOVW_SABS_G2 272
-
-/* PC-relative addresses */
-#define R_AARCH64_LD_PREL_LO19 273
-#define R_AARCH64_ADR_PREL_LO21 274
-#define R_AARCH64_ADR_PREL_PG_HI21 275
-#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
-#define R_AARCH64_ADD_ABS_LO12_NC 277
-#define R_AARCH64_LDST8_ABS_LO12_NC 278
-
-/* Control-flow relocations */
-#define R_AARCH64_TSTBR14 279
-#define R_AARCH64_CONDBR19 280
-#define R_AARCH64_JUMP26 282
-#define R_AARCH64_CALL26 283
-#define R_AARCH64_LDST16_ABS_LO12_NC 284
-#define R_AARCH64_LDST32_ABS_LO12_NC 285
-#define R_AARCH64_LDST64_ABS_LO12_NC 286
-#define R_AARCH64_LDST128_ABS_LO12_NC 299
-
-#define R_AARCH64_MOVW_PREL_G0 287
-#define R_AARCH64_MOVW_PREL_G0_NC 288
-#define R_AARCH64_MOVW_PREL_G1 289
-#define R_AARCH64_MOVW_PREL_G1_NC 290
-#define R_AARCH64_MOVW_PREL_G2 291
-#define R_AARCH64_MOVW_PREL_G2_NC 292
-#define R_AARCH64_MOVW_PREL_G3 293
-
-/* Dynamic relocations */
-#define R_AARCH64_COPY 1024
-#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */
-#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */
-#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
-#define R_AARCH64_TLS_DTPMOD 1028 /* Module index. */
-#define R_AARCH64_TLS_DTPREL 1029 /* Module-relative offset. */
-#define R_AARCH64_TLS_TPREL 1030 /* TP-relative offset. */
-#define R_AARCH64_TLSDESC 1031 /* 16-byte descriptor: resolver func + arg. */
-#define R_AARCH64_IRELATIVE 1032
-
-/* Dynamic array tags */
-#define DT_AARCH64_BTI_PLT 0x70000001
-#define DT_AARCH64_PAC_PLT 0x70000003
-#define DT_AARCH64_VARIANT_PCS 0x70000005
-
-#endif /* _AARCH64_ELF_MACHDEP_H_ */
diff --git a/libc/include/bits/elf_common.h b/libc/include/bits/elf_common.h
new file mode 100644
index 0000000..ea833f4
--- /dev/null
+++ b/libc/include/bits/elf_common.h
@@ -0,0 +1,1430 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2017, 2018 Dell EMC
+ * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien
+ * Copyright (c) 1998 John D. Polstra.
+ * 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$
+ */
+
+#ifndef _SYS_ELF_COMMON_H_
+#define _SYS_ELF_COMMON_H_ 1
+
+/*
+ * ELF definitions that are independent of architecture or word size.
+ */
+
+/*
+ * Option kinds.
+ */
+#define ODK_NULL 0 /* undefined */
+#define ODK_REGINFO 1 /* register usage info */
+#define ODK_EXCEPTIONS 2 /* exception processing info */
+#define ODK_PAD 3 /* section padding */
+#define ODK_HWPATCH 4 /* hardware patch applied */
+#define ODK_FILL 5 /* fill value used by the linker */
+#define ODK_TAGS 6 /* reserved space for tools */
+#define ODK_HWAND 7 /* hardware AND patch applied */
+#define ODK_HWOR 8 /* hardware OR patch applied */
+#define ODK_GP_GROUP 9 /* GP group for text/data sections */
+#define ODK_IDENT 10 /* ID information */
+#define ODK_PAGESIZE 11 /* page size information */
+
+/*
+ * ODK_EXCEPTIONS info field masks.
+ */
+#define OEX_FPU_MIN 0x0000001f /* min FPU exception required */
+#define OEX_FPU_MAX 0x00001f00 /* max FPU exception allowed */
+#define OEX_PAGE0 0x00010000 /* page zero must be mapped */
+#define OEX_SMM 0x00020000 /* run in sequential memory mode */
+#define OEX_PRECISEFP 0x00040000 /* run in precise FP exception mode */
+#define OEX_DISMISS 0x00080000 /* dismiss invalid address traps */
+
+/*
+ * ODK_PAD info field masks.
+ */
+#define OPAD_PREFIX 0x0001
+#define OPAD_POSTFIX 0x0002
+#define OPAD_SYMBOL 0x0004
+
+/*
+ * ODK_HWPATCH info field masks.
+ */
+#define OHW_R4KEOP 0x00000001 /* patch for R4000 branch at end-of-page bug */
+#define OHW_R8KPFETCH 0x00000002 /* R8000 prefetch bug may occur */
+#define OHW_R5KEOP 0x00000004 /* patch for R5000 branch at end-of-page bug */
+#define OHW_R5KCVTL 0x00000008 /* R5000 cvt.[ds].l bug: clean == 1 */
+#define OHW_R10KLDL 0x00000010UL /* need patch for R10000 misaligned load */
+
+/*
+ * ODK_HWAND/ODK_HWOR info field and hwp_flags[12] masks.
+ */
+#define OHWA0_R4KEOP_CHECKED 0x00000001 /* object checked for R4000 end-of-page bug */
+#define OHWA0_R4KEOP_CLEAN 0x00000002 /* object verified clean for R4000 end-of-page bug */
+#define OHWO0_FIXADE 0x00000001 /* object requires call to fixade */
+
+/*
+ * ODK_IDENT/ODK_GP_GROUP info field masks.
+ */
+#define OGP_GROUP 0x0000ffff /* GP group number */
+#define OGP_SELF 0x00010000 /* GP group is self-contained */
+
+/* Indexes into the e_ident array. Keep synced with
+ http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
+#define EI_MAG0 0 /* Magic number, byte 0. */
+#define EI_MAG1 1 /* Magic number, byte 1. */
+#define EI_MAG2 2 /* Magic number, byte 2. */
+#define EI_MAG3 3 /* Magic number, byte 3. */
+#define EI_CLASS 4 /* Class of machine. */
+#define EI_DATA 5 /* Data format. */
+#define EI_VERSION 6 /* ELF format version. */
+#define EI_OSABI 7 /* Operating system / ABI identification */
+#define EI_ABIVERSION 8 /* ABI version */
+#define OLD_EI_BRAND 8 /* Start of architecture identification. */
+#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
+#define EI_NIDENT 16 /* Size of e_ident array. */
+
+/* Values for the magic number bytes. */
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF" /* magic string */
+#define SELFMAG 4 /* magic string size */
+
+/* Values for e_ident[EI_VERSION] and e_version. */
+#define EV_NONE 0
+#define EV_CURRENT 1
+
+/* Values for e_ident[EI_CLASS]. */
+#define ELFCLASSNONE 0 /* Unknown class. */
+#define ELFCLASS32 1 /* 32-bit architecture. */
+#define ELFCLASS64 2 /* 64-bit architecture. */
+
+/* Values for e_ident[EI_DATA]. */
+#define ELFDATANONE 0 /* Unknown data format. */
+#define ELFDATA2LSB 1 /* 2's complement little-endian. */
+#define ELFDATA2MSB 2 /* 2's complement big-endian. */
+
+/* Values for e_ident[EI_OSABI]. */
+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
+#define ELFOSABI_HPUX 1 /* HP-UX operating system */
+#define ELFOSABI_NETBSD 2 /* NetBSD */
+#define ELFOSABI_LINUX 3 /* GNU/Linux */
+#define ELFOSABI_HURD 4 /* GNU/Hurd */
+#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
+#define ELFOSABI_SOLARIS 6 /* Solaris */
+#define ELFOSABI_AIX 7 /* AIX */
+#define ELFOSABI_IRIX 8 /* IRIX */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD */
+#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto */
+#define ELFOSABI_OPENBSD 12 /* OpenBSD */
+#define ELFOSABI_OPENVMS 13 /* Open VMS */
+#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
+#define ELFOSABI_AROS 15 /* Amiga Research OS */
+#define ELFOSABI_FENIXOS 16 /* FenixOS */
+#define ELFOSABI_CLOUDABI 17 /* Nuxi CloudABI */
+#define ELFOSABI_OPENVOS 18 /* Stratus Technologies OpenVOS */
+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
+
+#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */
+
+/* e_ident */
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+ (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* Values for e_type. */
+#define ET_NONE 0 /* Unknown type. */
+#define ET_REL 1 /* Relocatable. */
+#define ET_EXEC 2 /* Executable. */
+#define ET_DYN 3 /* Shared object. */
+#define ET_CORE 4 /* Core file. */
+#define ET_LOOS 0xfe00 /* First operating system specific. */
+#define ET_HIOS 0xfeff /* Last operating system-specific. */
+#define ET_LOPROC 0xff00 /* First processor-specific. */
+#define ET_HIPROC 0xffff /* Last processor-specific. */
+
+/* Values for e_machine. */
+#define EM_NONE 0 /* Unknown machine. */
+#define EM_M32 1 /* AT&T WE32100. */
+#define EM_SPARC 2 /* Sun SPARC. */
+#define EM_386 3 /* Intel i386. */
+#define EM_68K 4 /* Motorola 68000. */
+#define EM_88K 5 /* Motorola 88000. */
+#define EM_IAMCU 6 /* Intel MCU. */
+#define EM_860 7 /* Intel i860. */
+#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */
+#define EM_S370 9 /* IBM System/370. */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */
+#define EM_PARISC 15 /* HP PA-RISC. */
+#define EM_VPP500 17 /* Fujitsu VPP500. */
+#define EM_SPARC32PLUS 18 /* SPARC v8plus. */
+#define EM_960 19 /* Intel 80960. */
+#define EM_PPC 20 /* PowerPC 32-bit. */
+#define EM_PPC64 21 /* PowerPC 64-bit. */
+#define EM_S390 22 /* IBM System/390. */
+#define EM_V800 36 /* NEC V800. */
+#define EM_FR20 37 /* Fujitsu FR20. */
+#define EM_RH32 38 /* TRW RH-32. */
+#define EM_RCE 39 /* Motorola RCE. */
+#define EM_ARM 40 /* ARM. */
+#define EM_SH 42 /* Hitachi SH. */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit. */
+#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */
+#define EM_ARC 45 /* Argonaut RISC Core. */
+#define EM_H8_300 46 /* Hitachi H8/300. */
+#define EM_H8_300H 47 /* Hitachi H8/300H. */
+#define EM_H8S 48 /* Hitachi H8S. */
+#define EM_H8_500 49 /* Hitachi H8/500. */
+#define EM_IA_64 50 /* Intel IA-64 Processor. */
+#define EM_MIPS_X 51 /* Stanford MIPS-X. */
+#define EM_COLDFIRE 52 /* Motorola ColdFire. */
+#define EM_68HC12 53 /* Motorola M68HC12. */
+#define EM_MMA 54 /* Fujitsu MMA. */
+#define EM_PCP 55 /* Siemens PCP. */
+#define EM_NCPU 56 /* Sony nCPU. */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor. */
+#define EM_STARCORE 58 /* Motorola Star*Core processor. */
+#define EM_ME16 59 /* Toyota ME16 processor. */
+#define EM_ST100 60 /* STMicroelectronics ST100 processor. */
+#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */
+#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
+#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
+#define EM_PDSP 63 /* Sony DSP Processor. */
+#define EM_FX66 66 /* Siemens FX66 microcontroller. */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16
+ microcontroller. */
+#define EM_ST7 68 /* STmicroelectronics ST7 8-bit
+ microcontroller. */
+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */
+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */
+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */
+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */
+#define EM_SVX 73 /* Silicon Graphics SVx. */
+#define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */
+#define EM_VAX 75 /* Digital VAX. */
+#define EM_CRIS 76 /* Axis Communications 32-bit embedded
+ processor. */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded
+ processor. */
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */
+#define EM_HUANY 81 /* Harvard University machine-independent
+ object files. */
+#define EM_PRISM 82 /* SiTera Prism. */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */
+#define EM_FR30 84 /* Fujitsu FR30. */
+#define EM_D10V 85 /* Mitsubishi D10V. */
+#define EM_D30V 86 /* Mitsubishi D30V. */
+#define EM_V850 87 /* NEC v850. */
+#define EM_M32R 88 /* Mitsubishi M32R. */
+#define EM_MN10300 89 /* Matsushita MN10300. */
+#define EM_MN10200 90 /* Matsushita MN10200. */
+#define EM_PJ 91 /* picoJava. */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */
+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */
+#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */
+#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose
+ Processor. */
+#define EM_NS32K 97 /* National Semiconductor 32000 series. */
+#define EM_TPC 98 /* Tenor Network TPC processor. */
+#define EM_SNP1K 99 /* Trebia SNP 1000 processor. */
+#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */
+#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */
+#define EM_MAX 102 /* MAX Processor. */
+#define EM_CR 103 /* National Semiconductor CompactRISC
+ microprocessor. */
+#define EM_F2MC16 104 /* Fujitsu F2MC16. */
+#define EM_MSP430 105 /* Texas Instruments embedded microcontroller
+ msp430. */
+#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */
+#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */
+#define EM_SEP 108 /* Sharp embedded microprocessor. */
+#define EM_ARCA 109 /* Arca RISC Microprocessor. */
+#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd.
+ and MPRC of Peking University */
+#define EM_AARCH64 183 /* AArch64 (64-bit ARM) */
+#define EM_RISCV 243 /* RISC-V */
+
+/* Non-standard or deprecated. */
+#define EM_486 6 /* Intel i486. */
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
+#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */
+#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */
+
+/**
+ * e_flags
+ */
+#define EF_ARM_RELEXEC 0x1
+#define EF_ARM_HASENTRY 0x2
+#define EF_ARM_SYMSARESORTED 0x4
+#define EF_ARM_DYNSYMSUSESEGIDX 0x8
+#define EF_ARM_MAPSYMSFIRST 0x10
+#define EF_ARM_LE8 0x00400000
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_EABIMASK 0xFF000000
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+#define EF_ARM_INTERWORK 0x00000004
+#define EF_ARM_APCS_26 0x00000008
+#define EF_ARM_APCS_FLOAT 0x00000010
+#define EF_ARM_PIC 0x00000020
+#define EF_ARM_ALIGN8 0x00000040
+#define EF_ARM_NEW_ABI 0x00000080
+#define EF_ARM_OLD_ABI 0x00000100
+#define EF_ARM_ABI_FLOAT_SOFT 0x00000200
+#define EF_ARM_SOFT_FLOAT EF_ARM_ABI_FLOAT_SOFT /* Pre-V5 ABI name */
+#define EF_ARM_ABI_FLOAT_HARD 0x00000400
+#define EF_ARM_VFP_FLOAT EF_ARM_ABI_FLOAT_HARD /* Pre-V5 ABI name */
+#define EF_ARM_MAVERICK_FLOAT 0x00000800
+
+#define EF_MIPS_NOREORDER 0x00000001
+#define EF_MIPS_PIC 0x00000002 /* Contains PIC code */
+#define EF_MIPS_CPIC 0x00000004 /* STD PIC calling sequence */
+#define EF_MIPS_UCODE 0x00000010
+#define EF_MIPS_ABI2 0x00000020 /* N32 */
+#define EF_MIPS_OPTIONS_FIRST 0x00000080
+#define EF_MIPS_ABI 0x0000F000
+#define EF_MIPS_ABI_O32 0x00001000
+#define EF_MIPS_ABI_O64 0x00002000
+#define EF_MIPS_ABI_EABI32 0x00003000
+#define EF_MIPS_ABI_EABI64 0x00004000
+#define EF_MIPS_ARCH_ASE 0x0F000000 /* Architectural extensions */
+#define EF_MIPS_ARCH_ASE_MDMX 0x08000000 /* MDMX multimedia extension */
+#define EF_MIPS_ARCH_ASE_M16 0x04000000 /* MIPS-16 ISA extensions */
+#define EF_MIPS_ARCH 0xF0000000 /* Architecture field */
+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code */
+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code */
+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code */
+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code */
+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code */
+#define EF_MIPS_ARCH_32 0x50000000 /* -mips32 code */
+#define EF_MIPS_ARCH_64 0x60000000 /* -mips64 code */
+#define EF_MIPS_ARCH_32R2 0x70000000 /* -mips32r2 code */
+#define EF_MIPS_ARCH_64R2 0x80000000 /* -mips64r2 code */
+
+#define EF_PPC_EMB 0x80000000
+#define EF_PPC_RELOCATABLE 0x00010000
+#define EF_PPC_RELOCATABLE_LIB 0x00008000
+
+#define EF_RISCV_RVC 0x00000001
+#define EF_RISCV_FLOAT_ABI_MASK 0x00000006
+#define EF_RISCV_FLOAT_ABI_SOFT 0x00000000
+#define EF_RISCV_FLOAT_ABI_SINGLE 0x000002
+#define EF_RISCV_FLOAT_ABI_DOUBLE 0x000004
+#define EF_RISCV_FLOAT_ABI_QUAD 0x00000006
+#define EF_RISCV_RVE 0x00000008
+#define EF_RISCV_TSO 0x00000010
+
+#define EF_SPARC_EXT_MASK 0x00ffff00
+#define EF_SPARC_32PLUS 0x00000100
+#define EF_SPARC_SUN_US1 0x00000200
+#define EF_SPARC_HAL_R1 0x00000200
+#define EF_SPARC_SUN_US3 0x00000800
+
+#define EF_SPARCV9_MM 0x00000003
+#define EF_SPARCV9_TSO 0x00000000
+#define EF_SPARCV9_PSO 0x00000001
+#define EF_SPARCV9_RMO 0x00000002
+
+/* Special section indexes. */
+#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
+#define SHN_LORESERVE 0xff00 /* First of reserved range. */
+#define SHN_LOPROC 0xff00 /* First processor-specific. */
+#define SHN_HIPROC 0xff1f /* Last processor-specific. */
+#define SHN_LOOS 0xff20 /* First operating system-specific. */
+#define SHN_FBSD_CACHED SHN_LOOS /* Transient, for sys/kern/link_elf_obj
+ linker only: Cached global in local
+ symtab. */
+#define SHN_HIOS 0xff3f /* Last operating system-specific. */
+#define SHN_ABS 0xfff1 /* Absolute values. */
+#define SHN_COMMON 0xfff2 /* Common data. */
+#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
+#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
+
+/* sh_type */
+#define SHT_NULL 0 /* inactive */
+#define SHT_PROGBITS 1 /* program defined information */
+#define SHT_SYMTAB 2 /* symbol table section */
+#define SHT_STRTAB 3 /* string table section */
+#define SHT_RELA 4 /* relocation section with addends */
+#define SHT_HASH 5 /* symbol hash table section */
+#define SHT_DYNAMIC 6 /* dynamic section */
+#define SHT_NOTE 7 /* note section */
+#define SHT_NOBITS 8 /* no space section */
+#define SHT_REL 9 /* relocation section - no addends */
+#define SHT_SHLIB 10 /* reserved - purpose unknown */
+#define SHT_DYNSYM 11 /* dynamic symbol table section */
+#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */
+#define SHT_FINI_ARRAY 15 /* Termination function pointers. */
+#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */
+#define SHT_GROUP 17 /* Section group. */
+#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
+#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
+#define SHT_LOSUNW 0x6ffffff4
+#define SHT_SUNW_dof 0x6ffffff4
+#define SHT_SUNW_cap 0x6ffffff5
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5
+#define SHT_SUNW_SIGNATURE 0x6ffffff6
+#define SHT_GNU_HASH 0x6ffffff6
+#define SHT_GNU_LIBLIST 0x6ffffff7
+#define SHT_SUNW_ANNOTATE 0x6ffffff7
+#define SHT_SUNW_DEBUGSTR 0x6ffffff8
+#define SHT_SUNW_DEBUG 0x6ffffff9
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_SUNW_verdef 0x6ffffffd
+#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */
+#define SHT_SUNW_verneed 0x6ffffffe
+#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */
+#define SHT_SUNW_versym 0x6fffffff
+#define SHT_GNU_versym 0x6fffffff /* Symbol version table */
+#define SHT_HISUNW 0x6fffffff
+#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
+#define SHT_LOPROC 0x70000000 /* reserved range for processor */
+#define SHT_X86_64_UNWIND 0x70000001 /* unwind information */
+#define SHT_AMD64_UNWIND SHT_X86_64_UNWIND
+
+#define SHT_ARM_EXIDX 0x70000001 /* Exception index table. */
+#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking
+ pre-emption map. */
+#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility
+ attributes. */
+#define SHT_ARM_DEBUGOVERLAY 0x70000004 /* See DBGOVL for details. */
+#define SHT_ARM_OVERLAYSECTION 0x70000005 /* See DBGOVL for details. */
+#define SHT_MIPS_LIBLIST 0x70000000
+#define SHT_MIPS_MSYM 0x70000001
+#define SHT_MIPS_CONFLICT 0x70000002
+#define SHT_MIPS_GPTAB 0x70000003
+#define SHT_MIPS_UCODE 0x70000004
+#define SHT_MIPS_DEBUG 0x70000005
+#define SHT_MIPS_REGINFO 0x70000006
+#define SHT_MIPS_PACKAGE 0x70000007
+#define SHT_MIPS_PACKSYM 0x70000008
+#define SHT_MIPS_RELD 0x70000009
+#define SHT_MIPS_IFACE 0x7000000b
+#define SHT_MIPS_CONTENT 0x7000000c
+#define SHT_MIPS_OPTIONS 0x7000000d
+#define SHT_MIPS_DELTASYM 0x7000001b
+#define SHT_MIPS_DELTAINST 0x7000001c
+#define SHT_MIPS_DELTACLASS 0x7000001d
+#define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */
+#define SHT_MIPS_DELTADECL 0x7000001f
+#define SHT_MIPS_SYMBOL_LIB 0x70000020
+#define SHT_MIPS_EVENTS 0x70000021
+#define SHT_MIPS_TRANSLATE 0x70000022
+#define SHT_MIPS_PIXIE 0x70000023
+#define SHT_MIPS_XLATE 0x70000024
+#define SHT_MIPS_XLATE_DEBUG 0x70000025
+#define SHT_MIPS_WHIRL 0x70000026
+#define SHT_MIPS_EH_REGION 0x70000027
+#define SHT_MIPS_XLATE_OLD 0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+#define SHT_MIPS_ABIFLAGS 0x7000002a
+
+#define SHT_SPARC_GOTDATA 0x70000000
+
+#define SHTORDERED
+#define SHT_HIPROC 0x7fffffff /* specific section header types */
+#define SHT_LOUSER 0x80000000 /* reserved range for application */
+#define SHT_HIUSER 0xffffffff /* specific indexes */
+
+/* Flags for sh_flags. */
+#define SHF_WRITE 0x1 /* Section contains writable data. */
+#define SHF_ALLOC 0x2 /* Section occupies memory. */
+#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
+#define SHF_MERGE 0x10 /* Section may be merged. */
+#define SHF_STRINGS 0x20 /* Section contains strings. */
+#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */
+#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */
+#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */
+#define SHF_GROUP 0x200 /* Member of section group. */
+#define SHF_TLS 0x400 /* Section contains TLS data. */
+#define SHF_COMPRESSED 0x800 /* Section contains compressed data. */
+#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */
+#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */
+
+/* Flags for section groups. */
+#define GRP_COMDAT 0x1 /* COMDAT semantics. */
+
+/*
+ * Flags / mask for .gnu.versym sections.
+ */
+#define VERSYM_VERSION 0x7fff
+#define VERSYM_HIDDEN 0x8000
+
+/* Values for p_type. */
+#define PT_NULL 0 /* Unused entry. */
+#define PT_LOAD 1 /* Loadable segment. */
+#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
+#define PT_INTERP 3 /* Pathname of interpreter. */
+#define PT_NOTE 4 /* Auxiliary information. */
+#define PT_SHLIB 5 /* Reserved (not used). */
+#define PT_PHDR 6 /* Location of program header itself. */
+#define PT_TLS 7 /* Thread local storage segment */
+#define PT_LOOS 0x60000000 /* First OS-specific. */
+#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */
+#define PT_DUMP_DELTA 0x6fb5d000 /* va->pa map for kernel dumps
+ (currently arm). */
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
+#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */
+#define PT_SUNWDTRACE 0x6ffffffc /* private */
+#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6fffffff /* Last OS-specific. */
+#define PT_LOPROC 0x70000000 /* First processor-specific type. */
+#define PT_ARM_ARCHEXT 0x70000000 /* ARM arch compat information. */
+#define PT_ARM_EXIDX 0x70000001 /* ARM exception unwind tables. */
+#define PT_MIPS_REGINFO 0x70000000 /* MIPS register usage info */
+#define PT_MIPS_RTPROC 0x70000001 /* MIPS runtime procedure tbl */
+#define PT_MIPS_OPTIONS 0x70000002 /* MIPS e_flags value*/
+#define PT_MIPS_ABIFLAGS 0x70000003 /* MIPS fp mode */
+#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */
+
+#define PT_OPENBSD_RANDOMIZE 0x65A3DBE6 /* OpenBSD random data segment */
+#define PT_OPENBSD_WXNEEDED 0x65A3DBE7 /* OpenBSD EXEC/WRITE pages needed */
+#define PT_OPENBSD_BOOTDATA 0x65A41BE6 /* OpenBSD section for boot args */
+
+/* Values for p_flags. */
+#define PF_X 0x1 /* Executable. */
+#define PF_W 0x2 /* Writable. */
+#define PF_R 0x4 /* Readable. */
+#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */
+#define PF_MASKPROC 0xf0000000 /* Processor-specific. */
+
+/* Extended program header index. */
+#define PN_XNUM 0xffff
+
+/* Values for d_tag. */
+#define DT_NULL 0 /* Terminating entry. */
+#define DT_NEEDED 1 /* String table offset of a needed shared
+ library. */
+#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
+#define DT_PLTGOT 3 /* Processor-dependent address. */
+#define DT_HASH 4 /* Address of symbol hash table. */
+#define DT_STRTAB 5 /* Address of string table. */
+#define DT_SYMTAB 6 /* Address of symbol table. */
+#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
+#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
+#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
+#define DT_STRSZ 10 /* Size of string table. */
+#define DT_SYMENT 11 /* Size of each symbol table entry. */
+#define DT_INIT 12 /* Address of initialization function. */
+#define DT_FINI 13 /* Address of finalization function. */
+#define DT_SONAME 14 /* String table offset of shared object
+ name. */
+#define DT_RPATH 15 /* String table offset of library path. [sup] */
+#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
+#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
+#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
+#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
+#define DT_PLTREL 20 /* Type of relocation used for PLT. */
+#define DT_DEBUG 21 /* Reserved (not used). */
+#define DT_TEXTREL 22 /* Indicates there may be relocations in
+ non-writable segments. [sup] */
+#define DT_JMPREL 23 /* Address of PLT relocations. */
+#define DT_BIND_NOW 24 /* [sup] */
+#define DT_INIT_ARRAY 25 /* Address of the array of pointers to
+ initialization functions */
+#define DT_FINI_ARRAY 26 /* Address of the array of pointers to
+ termination functions */
+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of
+ initialization functions. */
+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of
+ termination functions. */
+#define DT_RUNPATH 29 /* String table offset of a null-terminated
+ library search path string. */
+#define DT_FLAGS 30 /* Object specific flag values. */
+#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING
+ and less than DT_LOOS follow the rules for
+ the interpretation of the d_un union
+ as follows: even == 'd_ptr', odd == 'd_val'
+ or none */
+#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to
+ pre-initialization functions. */
+#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of
+ pre-initialization functions. */
+#define DT_MAXPOSTAGS 34 /* number of positive tags */
+#define DT_RELRSZ 35 /* Total size of ElfNN_Relr relocations. */
+#define DT_RELR 36 /* Address of ElfNN_Relr relocations. */
+#define DT_RELRENT 37 /* Size of each ElfNN_Relr relocation. */
+#define DT_LOOS 0x6000000d /* First OS-specific */
+#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */
+#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */
+#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */
+#define DT_SUNW_CAP 0x60000010 /* hardware/software */
+#define DT_SUNW_ASLR 0x60000023 /* ASLR control */
+#define DT_HIOS 0x6ffff000 /* Last OS-specific */
+
+/*
+ * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+ * Dyn.d_un.d_val field of the Elf*_Dyn structure.
+ */
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5 /* prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* size of library list */
+#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */
+#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */
+#define DT_MOVEENT 0x6ffffdfa /* move table entry size */
+#define DT_MOVESZ 0x6ffffdfb /* move table size */
+#define DT_FEATURE 0x6ffffdfc /* feature holder */
+#define DT_FEATURE_1 DT_FEATURE
+#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */
+ /* the following DT_* entry. */
+ /* See DF_P1_* definitions */
+#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */
+#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */
+#define DT_VALRNGHI 0x6ffffdff
+
+/*
+ * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+ * Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+ *
+ * If any adjustment is made to the ELF object after it has been
+ * built, these entries will need to be adjusted.
+ */
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table */
+#define DT_TLSDESC_PLT 0x6ffffef6 /* loc. of PLT for tlsdesc resolver */
+#define DT_TLSDESC_GOT 0x6ffffef7 /* loc. of GOT for tlsdesc resolver */
+#define DT_GNU_CONFLICT 0x6ffffef8 /* address of conflict section */
+#define DT_GNU_LIBLIST 0x6ffffef9 /* address of library list */
+#define DT_CONFIG 0x6ffffefa /* configuration information */
+#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */
+#define DT_AUDIT 0x6ffffefc /* object auditing */
+#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */
+#define DT_MOVETAB 0x6ffffefe /* move table */
+#define DT_SYMINFO 0x6ffffeff /* syminfo table */
+#define DT_ADDRRNGHI 0x6ffffeff
+
+#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */
+#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */
+#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */
+#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */
+#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */
+#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */
+#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */
+#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */
+
+#define DT_LOPROC 0x70000000 /* First processor-specific type. */
+
+#define DT_AARCH64_BTI_PLT 0x70000001
+#define DT_AARCH64_PAC_PLT 0x70000003
+#define DT_AARCH64_VARIANT_PCS 0x70000005
+
+#define DT_ARM_SYMTABSZ 0x70000001
+#define DT_ARM_PREEMPTMAP 0x70000002
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_DEPRECATED_SPARC_REGISTER 0x7000001
+
+#define DT_MIPS_RLD_VERSION 0x70000001
+#define DT_MIPS_TIME_STAMP 0x70000002
+#define DT_MIPS_ICHECKSUM 0x70000003
+#define DT_MIPS_IVERSION 0x70000004
+#define DT_MIPS_FLAGS 0x70000005
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_CONFLICT 0x70000008
+#define DT_MIPS_LIBLIST 0x70000009
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+#define DT_MIPS_CONFLICTNO 0x7000000b
+#define DT_MIPS_LIBLISTNO 0x70000010
+#define DT_MIPS_SYMTABNO 0x70000011
+#define DT_MIPS_UNREFEXTNO 0x70000012
+#define DT_MIPS_GOTSYM 0x70000013
+#define DT_MIPS_HIPAGENO 0x70000014
+#define DT_MIPS_RLD_MAP 0x70000016
+#define DT_MIPS_DELTA_CLASS 0x70000017
+#define DT_MIPS_DELTA_CLASS_NO 0x70000018
+#define DT_MIPS_DELTA_INSTANCE 0x70000019
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001A
+#define DT_MIPS_DELTA_RELOC 0x7000001B
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001C
+#define DT_MIPS_DELTA_SYM 0x7000001D
+#define DT_MIPS_DELTA_SYM_NO 0x7000001E
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
+#define DT_MIPS_CXX_FLAGS 0x70000022
+#define DT_MIPS_PIXIE_INIT 0x70000023
+#define DT_MIPS_SYMBOL_LIB 0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS 0x70000029
+#define DT_MIPS_INTERFACE 0x7000002A
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002B
+#define DT_MIPS_INTERFACE_SIZE 0x7000002C
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002D
+#define DT_MIPS_PERF_SUFFIX 0x7000002E
+#define DT_MIPS_COMPACT_SIZE 0x7000002F
+#define DT_MIPS_GP_VALUE 0x70000030
+#define DT_MIPS_AUX_DYNAMIC 0x70000031
+#define DT_MIPS_PLTGOT 0x70000032
+#define DT_MIPS_RLD_OBJ_UPDATE 0x70000033
+#define DT_MIPS_RWPLT 0x70000034
+#define DT_MIPS_RLD_MAP_REL 0x70000035
+
+#define DT_PPC_GOT 0x70000000
+#define DT_PPC_TLSOPT 0x70000001
+
+#define DT_PPC64_GLINK 0x70000000
+#define DT_PPC64_OPD 0x70000001
+#define DT_PPC64_OPDSZ 0x70000002
+#define DT_PPC64_TLSOPT 0x70000003
+
+#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */
+#define DT_USED 0x7ffffffe /* ignored - same as needed */
+#define DT_FILTER 0x7fffffff /* shared library filter name */
+#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */
+
+/* Values for DT_FLAGS */
+#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may
+ make reference to the $ORIGIN substitution
+ string */
+#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */
+#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in
+ non-writable segments. */
+#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should
+ process all relocations for the object
+ containing this entry before transferring
+ control to the program. */
+#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or
+ executable contains code using a static
+ thread-local storage scheme. */
+
+/* Values for DT_FLAGS_1 */
+#define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */
+#define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */
+#define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */
+#define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filtees */
+#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */
+#define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */
+#define DF_1_INTERPOSE 0x00000400 /* Interpose all objects but main */
+#define DF_1_NODEFLIB 0x00000800 /* Do not search default paths */
+#define DF_1_PIE 0x08000000 /* Is position-independent executable */
+
+/* Values for l_flags. */
+#define LL_NONE 0x0 /* no flags */
+#define LL_EXACT_MATCH 0x1 /* require an exact match */
+#define LL_IGNORE_INT_VER 0x2 /* ignore version incompatibilities */
+#define LL_REQUIRE_MINOR 0x4
+#define LL_EXPORTS 0x8
+#define LL_DELAY_LOAD 0x10
+#define LL_DELTA 0x20
+
+/* Note section names */
+#define ELF_NOTE_FREEBSD "FreeBSD"
+#define ELF_NOTE_NETBSD "NetBSD"
+#define ELF_NOTE_SOLARIS "SUNW Solaris"
+#define ELF_NOTE_GNU "GNU"
+
+/* Values for n_type used in executables. */
+#define NT_FREEBSD_ABI_TAG 1
+#define NT_FREEBSD_NOINIT_TAG 2
+#define NT_FREEBSD_ARCH_TAG 3
+#define NT_FREEBSD_FEATURE_CTL 4
+
+/* NT_FREEBSD_FEATURE_CTL desc[0] bits */
+#define NT_FREEBSD_FCTL_ASLR_DISABLE 0x00000001
+#define NT_FREEBSD_FCTL_PROTMAX_DISABLE 0x00000002
+#define NT_FREEBSD_FCTL_STKGAP_DISABLE 0x00000004
+#define NT_FREEBSD_FCTL_WXNEEDED 0x00000008
+#define NT_FREEBSD_FCTL_LA48 0x00000010
+/* was ASG_DISABLE, do not reuse 0x00000020 */
+
+/* Values for n_type. Used in core files. */
+#define NT_PRSTATUS 1 /* Process status. */
+#define NT_FPREGSET 2 /* Floating point registers. */
+#define NT_PRPSINFO 3 /* Process state info. */
+#define NT_THRMISC 7 /* Thread miscellaneous info. */
+#define NT_PROCSTAT_PROC 8 /* Procstat proc data. */
+#define NT_PROCSTAT_FILES 9 /* Procstat files data. */
+#define NT_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */
+#define NT_PROCSTAT_GROUPS 11 /* Procstat groups data. */
+#define NT_PROCSTAT_UMASK 12 /* Procstat umask data. */
+#define NT_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */
+#define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */
+#define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */
+#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */
+#define NT_PTLWPINFO 17 /* Thread ptrace miscellaneous info. */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_X86_SEGBASES 0x200 /* x86 FS/GS base addresses. */
+#define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */
+#define NT_ARM_VFP 0x400 /* ARM VFP registers */
+#define NT_ARM_TLS 0x401 /* ARM TLS register */
+#define NT_ARM_ADDR_MASK 0x406 /* arm64 address mask (e.g. for TBI) */
+
+/* GNU note types. */
+#define NT_GNU_ABI_TAG 1
+#define NT_GNU_HWCAP 2
+#define NT_GNU_BUILD_ID 3
+#define NT_GNU_GOLD_VERSION 4
+#define NT_GNU_PROPERTY_TYPE_0 5
+
+#define GNU_PROPERTY_LOPROC 0xc0000000
+#define GNU_PROPERTY_HIPROC 0xdfffffff
+
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
+
+#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 0x00000002
+
+#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002
+
+#define GNU_PROPERTY_X86_FEATURE_1_IBT 0x00000001
+#define GNU_PROPERTY_X86_FEATURE_1_SHSTK 0x00000002
+
+/* Symbol Binding - ELFNN_ST_BIND - st_info */
+#define STB_LOCAL 0 /* Local symbol */
+#define STB_GLOBAL 1 /* Global symbol */
+#define STB_WEAK 2 /* like global - lower precedence */
+#define STB_LOOS 10 /* Start of operating system reserved range. */
+#define STB_GNU_UNIQUE 10 /* Unique symbol (GNU) */
+#define STB_HIOS 12 /* End of operating system reserved range. */
+#define STB_LOPROC 13 /* reserved range for processor */
+#define STB_HIPROC 15 /* specific semantics. */
+
+/* Symbol type - ELFNN_ST_TYPE - st_info */
+#define STT_NOTYPE 0 /* Unspecified type. */
+#define STT_OBJECT 1 /* Data object. */
+#define STT_FUNC 2 /* Function. */
+#define STT_SECTION 3 /* Section. */
+#define STT_FILE 4 /* Source file. */
+#define STT_COMMON 5 /* Uninitialized common block. */
+#define STT_TLS 6 /* TLS object. */
+#define STT_NUM 7
+#define STT_LOOS 10 /* Reserved range for operating system */
+#define STT_GNU_IFUNC 10
+#define STT_HIOS 12 /* specific semantics. */
+#define STT_LOPROC 13 /* Start of processor reserved range. */
+#define STT_SPARC_REGISTER 13 /* SPARC register information. */
+#define STT_HIPROC 15 /* End of processor reserved range. */
+
+/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
+#define STV_DEFAULT 0x0 /* Default visibility (see binding). */
+#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */
+#define STV_HIDDEN 0x2 /* Not visible. */
+#define STV_PROTECTED 0x3 /* Visible but not preemptible. */
+#define STV_EXPORTED 0x4
+#define STV_SINGLETON 0x5
+#define STV_ELIMINATE 0x6
+
+/* Special symbol table indexes. */
+#define STN_UNDEF 0 /* Undefined symbol index. */
+
+/* Symbol versioning flags. */
+#define VER_DEF_CURRENT 1
+#define VER_DEF_IDX(x) VER_NDX(x)
+
+#define VER_FLG_BASE 0x01
+#define VER_FLG_WEAK 0x02
+
+#define VER_NEED_CURRENT 1
+#define VER_NEED_WEAK (1u << 15)
+#define VER_NEED_HIDDEN VER_NDX_HIDDEN
+#define VER_NEED_IDX(x) VER_NDX(x)
+
+#define VER_NDX_LOCAL 0
+#define VER_NDX_GLOBAL 1
+#define VER_NDX_GIVEN 2
+
+#define VER_NDX_HIDDEN (1u << 15)
+#define VER_NDX(x) ((x) & ~(1u << 15))
+
+#define CA_SUNW_NULL 0
+#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */
+#define CA_SUNW_SF_1 2 /* first software capabilities entry */
+
+/*
+ * Syminfo flag values
+ */
+#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */
+ /* to object containing defn. */
+#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */
+#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */
+ /* lazily-loaded */
+#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */
+ /* object containing defn. */
+#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */
+ /* directly bind to this symbol */
+#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */
+#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */
+
+/*
+ * Syminfo.si_boundto values.
+ */
+#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */
+#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */
+#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */
+#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */
+#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */
+
+/*
+ * Syminfo version values.
+ */
+#define SYMINFO_NONE 0 /* Syminfo version */
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+/* Values for ch_type (compressed section headers). */
+#define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE */
+#define ELFCOMPRESS_ZSTD 2 /* Zstandard */
+#define ELFCOMPRESS_LOOS 0x60000000 /* OS-specific */
+#define ELFCOMPRESS_HIOS 0x6fffffff
+#define ELFCOMPRESS_LOPROC 0x70000000 /* Processor-specific */
+#define ELFCOMPRESS_HIPROC 0x7fffffff
+
+/*
+ * Relocation types.
+ *
+ * All machine architectures are defined here to allow tools on one to
+ * handle others.
+ */
+
+#define R_386_NONE 0 /* No relocation. */
+#define R_386_32 1 /* Add symbol value. */
+#define R_386_PC32 2 /* Add PC-relative symbol value. */
+#define R_386_GOT32 3 /* Add PC-relative GOT offset. */
+#define R_386_PLT32 4 /* Add PC-relative PLT offset. */
+#define R_386_COPY 5 /* Copy data from shared object. */
+#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */
+#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */
+#define R_386_RELATIVE 8 /* Add load address of shared object. */
+#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */
+#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */
+#define R_386_32PLT 11
+#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */
+#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */
+#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */
+#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */
+#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_16 20
+#define R_386_PC16 21
+#define R_386_8 22
+#define R_386_PC8 23
+#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */
+#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */
+#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */
+#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */
+#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */
+#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */
+#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */
+#define R_386_SIZE32 38
+#define R_386_TLS_GOTDESC 39
+#define R_386_TLS_DESC_CALL 40
+#define R_386_TLS_DESC 41
+#define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */
+#define R_386_GOT32X 43
+
+#define R_AARCH64_NONE 0 /* No relocation */
+#define R_AARCH64_ABS64 257 /* Absolute offset */
+#define R_AARCH64_ABS32 258 /* Absolute, 32-bit overflow check */
+#define R_AARCH64_ABS16 259 /* Absolute, 16-bit overflow check */
+#define R_AARCH64_PREL64 260 /* PC relative */
+#define R_AARCH64_PREL32 261 /* PC relative, 32-bit overflow check */
+#define R_AARCH64_PREL16 262 /* PC relative, 16-bit overflow check */
+#define R_AARCH64_TSTBR14 279 /* TBZ/TBNZ immediate */
+#define R_AARCH64_CONDBR19 280 /* Conditional branch immediate */
+#define R_AARCH64_JUMP26 282 /* Branch immediate */
+#define R_AARCH64_CALL26 283 /* Call immediate */
+#define R_AARCH64_COPY 1024 /* Copy data from shared object */
+#define R_AARCH64_GLOB_DAT 1025 /* Set GOT entry to data address */
+#define R_AARCH64_JUMP_SLOT 1026 /* Set GOT entry to code address */
+#define R_AARCH64_RELATIVE 1027 /* Add load address of shared object */
+#define R_AARCH64_TLS_DTPREL64 1028
+#define R_AARCH64_TLS_DTPMOD64 1029
+#define R_AARCH64_TLS_TPREL64 1030
+#define R_AARCH64_TLSDESC 1031 /* Identify the TLS descriptor */
+#define R_AARCH64_IRELATIVE 1032
+
+#define R_ARM_NONE 0 /* No relocation. */
+#define R_ARM_PC24 1
+#define R_ARM_ABS32 2
+#define R_ARM_REL32 3
+#define R_ARM_PC13 4
+#define R_ARM_ABS16 5
+#define R_ARM_ABS12 6
+#define R_ARM_THM_ABS5 7
+#define R_ARM_ABS8 8
+#define R_ARM_SBREL32 9
+#define R_ARM_THM_PC22 10
+#define R_ARM_THM_PC8 11
+#define R_ARM_AMP_VCALL9 12
+#define R_ARM_SWI24 13
+#define R_ARM_THM_SWI8 14
+#define R_ARM_XPC25 15
+#define R_ARM_THM_XPC22 16
+/* TLS relocations */
+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
+#define R_ARM_COPY 20 /* Copy data from shared object. */
+#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */
+#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */
+#define R_ARM_RELATIVE 23 /* Add load address of shared object. */
+#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */
+#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */
+#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */
+#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */
+#define R_ARM_GNU_VTENTRY 100
+#define R_ARM_GNU_VTINHERIT 101
+#define R_ARM_RSBREL32 250
+#define R_ARM_THM_RPC22 251
+#define R_ARM_RREL32 252
+#define R_ARM_RABS32 253
+#define R_ARM_RPC24 254
+#define R_ARM_RBASE 255
+
+/* Name Value Field Calculation */
+#define R_IA_64_NONE 0 /* None */
+#define R_IA_64_IMM14 0x21 /* immediate14 S + A */
+#define R_IA_64_IMM22 0x22 /* immediate22 S + A */
+#define R_IA_64_IMM64 0x23 /* immediate64 S + A */
+#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */
+#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */
+#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */
+#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */
+#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */
+#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */
+#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */
+#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */
+#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */
+#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */
+#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */
+#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */
+#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */
+#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */
+#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */
+#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */
+#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */
+#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */
+#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */
+#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */
+#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */
+#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */
+#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */
+#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */
+#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */
+#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */
+#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */
+#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */
+#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */
+#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */
+#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */
+#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */
+#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */
+#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */
+#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */
+#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */
+#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */
+#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */
+#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */
+#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */
+#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */
+#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */
+#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */
+#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */
+#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */
+#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */
+#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */
+#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */
+#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */
+#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */
+#define R_IA_64_SUB 0x85 /* immediate64 A - S */
+#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */
+#define R_IA_64_LDXMOV 0x87 /* immediate22 special */
+#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */
+#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */
+#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */
+#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */
+#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */
+#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */
+#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */
+#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */
+#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */
+#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */
+#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */
+#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */
+#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */
+#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */
+#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */
+#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */
+#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */
+
+#define R_MIPS_NONE 0 /* No reloc */
+#define R_MIPS_16 1 /* Direct 16 bit */
+#define R_MIPS_32 2 /* Direct 32 bit */
+#define R_MIPS_REL32 3 /* PC relative 32 bit */
+#define R_MIPS_26 4 /* Direct 26 bit shifted */
+#define R_MIPS_HI16 5 /* High 16 bit */
+#define R_MIPS_LO16 6 /* Low 16 bit */
+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
+#define R_MIPS_PC16 10 /* PC relative 16 bit */
+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
+#define R_MIPS_64 18 /* Direct 64 bit */
+#define R_MIPS_GOT_DISP 19
+#define R_MIPS_GOT_PAGE 20
+#define R_MIPS_GOT_OFST 21
+#define R_MIPS_GOT_HI16 22 /* GOT HI 16 bit */
+#define R_MIPS_GOT_LO16 23 /* GOT LO 16 bit */
+#define R_MIPS_SUB 24
+#define R_MIPS_CALLHI16 30 /* upper 16 bit GOT entry for function */
+#define R_MIPS_CALLLO16 31 /* lower 16 bit GOT entry for function */
+#define R_MIPS_JALR 37
+#define R_MIPS_TLS_GD 42
+#define R_MIPS_COPY 126
+#define R_MIPS_JUMP_SLOT 127
+
+#define R_PPC_NONE 0 /* No relocation. */
+#define R_PPC_ADDR32 1
+#define R_PPC_ADDR24 2
+#define R_PPC_ADDR16 3
+#define R_PPC_ADDR16_LO 4
+#define R_PPC_ADDR16_HI 5
+#define R_PPC_ADDR16_HA 6
+#define R_PPC_ADDR14 7
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10
+#define R_PPC_REL14 11
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+#define R_PPC_IRELATIVE 248
+
+/*
+ * 64-bit relocations
+ */
+#define R_PPC64_ADDR64 38
+#define R_PPC64_ADDR16_HIGHER 39
+#define R_PPC64_ADDR16_HIGHERA 40
+#define R_PPC64_ADDR16_HIGHEST 41
+#define R_PPC64_ADDR16_HIGHESTA 42
+#define R_PPC64_UADDR64 43
+#define R_PPC64_REL64 44
+#define R_PPC64_PLT64 45
+#define R_PPC64_PLTREL64 46
+#define R_PPC64_TOC16 47
+#define R_PPC64_TOC16_LO 48
+#define R_PPC64_TOC16_HI 49
+#define R_PPC64_TOC16_HA 50
+#define R_PPC64_TOC 51
+#define R_PPC64_DTPMOD64 68
+#define R_PPC64_TPREL64 73
+#define R_PPC64_DTPREL64 78
+
+/*
+ * TLS relocations
+ */
+#define R_PPC_TLS 67
+#define R_PPC_DTPMOD32 68
+#define R_PPC_TPREL16 69
+#define R_PPC_TPREL16_LO 70
+#define R_PPC_TPREL16_HI 71
+#define R_PPC_TPREL16_HA 72
+#define R_PPC_TPREL32 73
+#define R_PPC_DTPREL16 74
+#define R_PPC_DTPREL16_LO 75
+#define R_PPC_DTPREL16_HI 76
+#define R_PPC_DTPREL16_HA 77
+#define R_PPC_DTPREL32 78
+#define R_PPC_GOT_TLSGD16 79
+#define R_PPC_GOT_TLSGD16_LO 80
+#define R_PPC_GOT_TLSGD16_HI 81
+#define R_PPC_GOT_TLSGD16_HA 82
+#define R_PPC_GOT_TLSLD16 83
+#define R_PPC_GOT_TLSLD16_LO 84
+#define R_PPC_GOT_TLSLD16_HI 85
+#define R_PPC_GOT_TLSLD16_HA 86
+#define R_PPC_GOT_TPREL16 87
+#define R_PPC_GOT_TPREL16_LO 88
+#define R_PPC_GOT_TPREL16_HI 89
+#define R_PPC_GOT_TPREL16_HA 90
+
+/*
+ * The remaining relocs are from the Embedded ELF ABI, and are not in the
+ * SVR4 ELF ABI.
+ */
+
+#define R_PPC_EMB_NADDR32 101
+#define R_PPC_EMB_NADDR16 102
+#define R_PPC_EMB_NADDR16_LO 103
+#define R_PPC_EMB_NADDR16_HI 104
+#define R_PPC_EMB_NADDR16_HA 105
+#define R_PPC_EMB_SDAI16 106
+#define R_PPC_EMB_SDA2I16 107
+#define R_PPC_EMB_SDA2REL 108
+#define R_PPC_EMB_SDA21 109
+#define R_PPC_EMB_MRKREF 110
+#define R_PPC_EMB_RELSEC16 111
+#define R_PPC_EMB_RELST_LO 112
+#define R_PPC_EMB_RELST_HI 113
+#define R_PPC_EMB_RELST_HA 114
+#define R_PPC_EMB_BIT_FLD 115
+#define R_PPC_EMB_RELSDA 116
+
+/*
+ * RISC-V relocation types.
+ */
+
+/* Relocation types used by the dynamic linker. */
+#define R_RISCV_NONE 0
+#define R_RISCV_32 1
+#define R_RISCV_64 2
+#define R_RISCV_RELATIVE 3
+#define R_RISCV_COPY 4
+#define R_RISCV_JUMP_SLOT 5
+#define R_RISCV_TLS_DTPMOD32 6
+#define R_RISCV_TLS_DTPMOD64 7
+#define R_RISCV_TLS_DTPREL32 8
+#define R_RISCV_TLS_DTPREL64 9
+#define R_RISCV_TLS_TPREL32 10
+#define R_RISCV_TLS_TPREL64 11
+
+/* Relocation types not used by the dynamic linker. */
+#define R_RISCV_BRANCH 16
+#define R_RISCV_JAL 17
+#define R_RISCV_CALL 18
+#define R_RISCV_CALL_PLT 19
+#define R_RISCV_GOT_HI20 20
+#define R_RISCV_TLS_GOT_HI20 21
+#define R_RISCV_TLS_GD_HI20 22
+#define R_RISCV_PCREL_HI20 23
+#define R_RISCV_PCREL_LO12_I 24
+#define R_RISCV_PCREL_LO12_S 25
+#define R_RISCV_HI20 26
+#define R_RISCV_LO12_I 27
+#define R_RISCV_LO12_S 28
+#define R_RISCV_TPREL_HI20 29
+#define R_RISCV_TPREL_LO12_I 30
+#define R_RISCV_TPREL_LO12_S 31
+#define R_RISCV_TPREL_ADD 32
+#define R_RISCV_ADD8 33
+#define R_RISCV_ADD16 34
+#define R_RISCV_ADD32 35
+#define R_RISCV_ADD64 36
+#define R_RISCV_SUB8 37
+#define R_RISCV_SUB16 38
+#define R_RISCV_SUB32 39
+#define R_RISCV_SUB64 40
+#define R_RISCV_GNU_VTINHERIT 41
+#define R_RISCV_GNU_VTENTRY 42
+#define R_RISCV_ALIGN 43
+#define R_RISCV_RVC_BRANCH 44
+#define R_RISCV_RVC_JUMP 45
+#define R_RISCV_RVC_LUI 46
+#define R_RISCV_RELAX 51
+#define R_RISCV_SUB6 52
+#define R_RISCV_SET6 53
+#define R_RISCV_SET8 54
+#define R_RISCV_SET16 55
+#define R_RISCV_SET32 56
+#define R_RISCV_32_PCREL 57
+#define R_RISCV_IRELATIVE 58
+
+#define R_SPARC_NONE 0
+#define R_SPARC_8 1
+#define R_SPARC_16 2
+#define R_SPARC_32 3
+#define R_SPARC_DISP8 4
+#define R_SPARC_DISP16 5
+#define R_SPARC_DISP32 6
+#define R_SPARC_WDISP30 7
+#define R_SPARC_WDISP22 8
+#define R_SPARC_HI22 9
+#define R_SPARC_22 10
+#define R_SPARC_13 11
+#define R_SPARC_LO10 12
+#define R_SPARC_GOT10 13
+#define R_SPARC_GOT13 14
+#define R_SPARC_GOT22 15
+#define R_SPARC_PC10 16
+#define R_SPARC_PC22 17
+#define R_SPARC_WPLT30 18
+#define R_SPARC_COPY 19
+#define R_SPARC_GLOB_DAT 20
+#define R_SPARC_JMP_SLOT 21
+#define R_SPARC_RELATIVE 22
+#define R_SPARC_UA32 23
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_64 32
+#define R_SPARC_OLO10 33
+#define R_SPARC_HH22 34
+#define R_SPARC_HM10 35
+#define R_SPARC_LM22 36
+#define R_SPARC_PC_HH22 37
+#define R_SPARC_PC_HM10 38
+#define R_SPARC_PC_LM22 39
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_GLOB_JMP 42
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+#define R_SPARC_DISP64 46
+#define R_SPARC_PLT64 47
+#define R_SPARC_HIX22 48
+#define R_SPARC_LOX10 49
+#define R_SPARC_H44 50
+#define R_SPARC_M44 51
+#define R_SPARC_L44 52
+#define R_SPARC_REGISTER 53
+#define R_SPARC_UA64 54
+#define R_SPARC_UA16 55
+#define R_SPARC_TLS_GD_HI22 56
+#define R_SPARC_TLS_GD_LO10 57
+#define R_SPARC_TLS_GD_ADD 58
+#define R_SPARC_TLS_GD_CALL 59
+#define R_SPARC_TLS_LDM_HI22 60
+#define R_SPARC_TLS_LDM_LO10 61
+#define R_SPARC_TLS_LDM_ADD 62
+#define R_SPARC_TLS_LDM_CALL 63
+#define R_SPARC_TLS_LDO_HIX22 64
+#define R_SPARC_TLS_LDO_LOX10 65
+#define R_SPARC_TLS_LDO_ADD 66
+#define R_SPARC_TLS_IE_HI22 67
+#define R_SPARC_TLS_IE_LO10 68
+#define R_SPARC_TLS_IE_LD 69
+#define R_SPARC_TLS_IE_LDX 70
+#define R_SPARC_TLS_IE_ADD 71
+#define R_SPARC_TLS_LE_HIX22 72
+#define R_SPARC_TLS_LE_LOX10 73
+#define R_SPARC_TLS_DTPMOD32 74
+#define R_SPARC_TLS_DTPMOD64 75
+#define R_SPARC_TLS_DTPOFF32 76
+#define R_SPARC_TLS_DTPOFF64 77
+#define R_SPARC_TLS_TPOFF32 78
+#define R_SPARC_TLS_TPOFF64 79
+
+#define R_X86_64_NONE 0 /* No relocation. */
+#define R_X86_64_64 1 /* Add 64 bit symbol value. */
+#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */
+#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */
+#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */
+#define R_X86_64_COPY 5 /* Copy data from shared object. */
+#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */
+#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */
+#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */
+#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */
+#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */
+#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */
+#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */
+#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */
+#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */
+#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */
+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */
+#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */
+#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */
+#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */
+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
+#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */
+#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */
+#define R_X86_64_PC64 24 /* PC-relative 64 bit signed sym value. */
+#define R_X86_64_GOTOFF64 25
+#define R_X86_64_GOTPC32 26
+#define R_X86_64_GOT64 27
+#define R_X86_64_GOTPCREL64 28
+#define R_X86_64_GOTPC64 29
+#define R_X86_64_GOTPLT64 30
+#define R_X86_64_PLTOFF64 31
+#define R_X86_64_SIZE32 32
+#define R_X86_64_SIZE64 33
+#define R_X86_64_GOTPC32_TLSDESC 34
+#define R_X86_64_TLSDESC_CALL 35
+#define R_X86_64_TLSDESC 36
+#define R_X86_64_IRELATIVE 37
+#define R_X86_64_RELATIVE64 38
+/* 39 and 40 were BND-related, already decomissioned */
+#define R_X86_64_GOTPCRELX 41
+#define R_X86_64_REX_GOTPCRELX 42
+
+#define ELF_BSDF_SIGFASTBLK 0x0001 /* Kernel supports fast sigblock */
+#define ELF_BSDF_VMNOOVERCOMMIT 0x0002
+
+#endif /* !_SYS_ELF_COMMON_H_ */
diff --git a/libc/include/bits/elf_x86.h b/libc/include/bits/elf_x86.h
deleted file mode 100644
index dfbaba0..0000000
--- a/libc/include/bits/elf_x86.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* $NetBSD: elf_machdep.h,v 1.12 2016/02/02 20:16:59 christos Exp $ */
-
-#ifndef _X86_ELF_MACHDEP_H_
-#define _X86_ELF_MACHDEP_H_
-
-/* i386 relocations */
-#define R_386_NONE 0
-#define R_386_32 1
-#define R_386_PC32 2
-#define R_386_GOT32 3
-#define R_386_PLT32 4
-#define R_386_COPY 5
-#define R_386_GLOB_DAT 6
-#define R_386_JMP_SLOT 7
-#define R_386_RELATIVE 8
-#define R_386_GOTOFF 9
-#define R_386_GOTPC 10
-#define R_386_32PLT 11
-
-/* TLS relocations */
-#define R_386_TLS_TPOFF 14
-#define R_386_TLS_IE 15
-#define R_386_TLS_GOTIE 16
-#define R_386_TLS_LE 17
-#define R_386_TLS_GD 18
-#define R_386_TLS_LDM 19
-
-/* The following relocations are GNU extensions. */
-#define R_386_16 20
-#define R_386_PC16 21
-#define R_386_8 22
-#define R_386_PC8 23
-
-/* More TLS relocations */
-#define R_386_TLS_GD_32 24
-#define R_386_TLS_GD_PUSH 25
-#define R_386_TLS_GD_CALL 26
-#define R_386_TLS_GD_POP 27
-#define R_386_TLS_LDM_32 28
-#define R_386_TLS_LDM_PUSH 29
-#define R_386_TLS_LDM_CALL 30
-#define R_386_TLS_LDM_POP 31
-#define R_386_TLS_LDO_32 32
-#define R_386_TLS_IE_32 33
-#define R_386_TLS_LE_32 34
-#define R_386_TLS_DTPMOD32 35
-#define R_386_TLS_DTPOFF32 36
-#define R_386_TLS_TPOFF32 37
-
-#define R_386_SIZE32 38
-
-/* More TLS relocations */
-#define R_386_TLS_GOTDESC 39
-#define R_386_TLS_DESC_CALL 40
-#define R_386_TLS_DESC 41
-
-#define R_386_IRELATIVE 42
-#define R_386_GOT32X 43
-
-#endif
diff --git a/libc/include/bits/elf_x86_64.h b/libc/include/bits/elf_x86_64.h
deleted file mode 100644
index 30062af..0000000
--- a/libc/include/bits/elf_x86_64.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* $NetBSD: elf_machdep.h,v 1.5 2016/02/02 20:13:59 christos Exp $ */
-
-#ifndef _X86_64_ELF_MACHDEP_H_
-#define _X86_64_ELF_MACHDEP_H_
-
-/* x86-64 relocations */
-
-#define R_X86_64_NONE 0
-#define R_X86_64_64 1
-#define R_X86_64_PC32 2
-#define R_X86_64_GOT32 3
-#define R_X86_64_PLT32 4
-#define R_X86_64_COPY 5
-#define R_X86_64_GLOB_DAT 6
-#define R_X86_64_JUMP_SLOT 7
-#define R_X86_64_RELATIVE 8
-#define R_X86_64_GOTPCREL 9
-#define R_X86_64_32 10
-#define R_X86_64_32S 11
-#define R_X86_64_16 12
-#define R_X86_64_PC16 13
-#define R_X86_64_8 14
-#define R_X86_64_PC8 15
-
-/* TLS relocations */
-#define R_X86_64_DTPMOD64 16
-#define R_X86_64_DTPOFF64 17
-#define R_X86_64_TPOFF64 18
-#define R_X86_64_TLSGD 19
-#define R_X86_64_TLSLD 20
-#define R_X86_64_DTPOFF32 21
-#define R_X86_64_GOTTPOFF 22
-#define R_X86_64_TPOFF32 23
-
-#define R_X86_64_PC64 24
-#define R_X86_64_GOTOFF64 25
-#define R_X86_64_GOTPC32 26
-#define R_X86_64_GOT64 27
-#define R_X86_64_GOTPCREL64 28
-#define R_X86_64_GOTPC64 29
-#define R_X86_64_GOTPLT64 30
-#define R_X86_64_PLTOFF64 31
-#define R_X86_64_SIZE32 32
-#define R_X86_64_SIZE64 33
-#define R_X86_64_GOTPC32_TLSDESC 34
-#define R_X86_64_TLSDESC_CALL 35
-#define R_X86_64_TLSDESC 36
-#define R_X86_64_IRELATIVE 37
-#define R_X86_64_RELATIVE64 38
-#define R_X86_64_PC32_BND 39
-#define R_X86_64_PLT32_BND 40
-#define R_X86_64_GOTPCRELX 41
-#define R_X86_64_REX_GOTPCRELX 42
-
-#endif
diff --git a/libc/include/bits/fenv_riscv64.h b/libc/include/bits/fenv_riscv64.h
new file mode 100644
index 0000000..e1e43b6
--- /dev/null
+++ b/libc/include/bits/fenv_riscv64.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+typedef __uint32_t fenv_t;
+typedef __uint32_t fexcept_t;
+
+/* Exception flags. No FE_DENORMAL for riscv64. */
+#define FE_INEXACT 0x01
+#define FE_UNDERFLOW 0x02
+#define FE_OVERFLOW 0x04
+#define FE_DIVBYZERO 0x08
+#define FE_INVALID 0x10
+#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
+
+/* Rounding modes. */
+#define FE_TONEAREST 0x0
+#define FE_TOWARDZERO 0x1
+#define FE_DOWNWARD 0x2
+#define FE_UPWARD 0x3
+
+__END_DECLS
diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h
index 7063541..7fe60f4 100644
--- a/libc/include/bits/fortify/fcntl.h
+++ b/libc/include/bits/fortify/fcntl.h
@@ -41,7 +41,7 @@
#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?"
+#define __open_useless_modes_warning "has superfluous mode bits; missing O_CREAT or O_TMPFILE?"
/* O_TMPFILE shares bits with O_DIRECTORY. */
#define __open_modes_useful(flags) (((flags) & O_CREAT) || ((flags) & O_TMPFILE) == O_TMPFILE)
diff --git a/libc/include/elf.h b/libc/include/elf.h
index 4739bbd..1dfc008 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -30,13 +30,12 @@
#include <sys/cdefs.h>
-#include <bits/auxvec.h>
-#include <bits/elf_arm.h>
-#include <bits/elf_arm64.h>
-#include <bits/elf_x86.h>
-#include <bits/elf_x86_64.h>
#include <linux/elf.h>
#include <linux/elf-em.h>
+#undef EI_PAD
+
+#include <bits/auxvec.h>
+#include <bits/elf_common.h>
/* http://www.sco.com/developers/gabi/latest/ch4.intro.html */
typedef __u64 Elf32_Xword;
@@ -83,14 +82,6 @@
Elf64_Word l_version;
Elf64_Word l_flags;
} Elf64_Lib;
-/* ElfW(Lib)::l_flags values. */
-#define LL_NONE 0x0
-#define LL_EXACT_MATCH 0x1
-#define LL_IGNORE_INT_VER 0x2
-#define LL_REQUIRE_MINOR 0x4
-#define LL_EXPORTS 0x8
-#define LL_DELAY_LOAD 0x10
-#define LL_DELTA 0x20
typedef struct {
Elf32_Xword m_value;
@@ -118,14 +109,6 @@
Elf64_Half si_boundto;
Elf64_Half si_flags;
} Elf64_Syminfo;
-/* ElfW(Syminfo)::si_boundto values. */
-#define SYMINFO_BT_SELF 0xffff
-#define SYMINFO_BT_PARENT 0xfffe
-/* ElfW(Syminfo)::si_flags values. */
-#define SYMINFO_FLG_DIRECT 0x1
-#define SYMINFO_FLG_PASSTHRU 0x2
-#define SYMINFO_FLG_COPY 0x4
-#define SYMINFO_FLG_LAZYLOAD 0x8
typedef Elf32_Half Elf32_Versym;
typedef Elf64_Half Elf64_Versym;
@@ -197,24 +180,12 @@
typedef Elf64_Xword Elf64_Relr;
/* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html */
-#define DF_ORIGIN 0x00000001
-#define DF_SYMBOLIC 0x00000002
-#define DF_TEXTREL 0x00000004
-#define DF_BIND_NOW 0x00000008
-#define DF_STATIC_TLS 0x00000010
#define DF_1_NOW 0x00000001 /* Perform complete relocation processing. */
-#define DF_1_GLOBAL 0x00000002 /* implies RTLD_GLOBAL */
#define DF_1_GROUP 0x00000004
-#define DF_1_NODELETE 0x00000008 /* implies RTLD_NODELETE */
-#define DF_1_LOADFLTR 0x00000010
#define DF_1_INITFIRST 0x00000020
-#define DF_1_NOOPEN 0x00000040 /* Object can not be used with dlopen(3) */
-#define DF_1_ORIGIN 0x00000080
#define DF_1_DIRECT 0x00000100
#define DF_1_TRANS 0x00000200
-#define DF_1_INTERPOSE 0x00000400
-#define DF_1_NODEFLIB 0x00000800
#define DF_1_NODUMP 0x00001000 /* Object cannot be dumped with dldump(3) */
#define DF_1_CONFALT 0x00002000
#define DF_1_ENDFILTEE 0x00004000
@@ -230,58 +201,10 @@
#define DF_1_GLOBAUDIT 0x01000000
#define DF_1_SINGLETON 0x02000000
#define DF_1_STUB 0x04000000
-#define DF_1_PIE 0x08000000
-
-/* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html */
-#define DT_BIND_NOW 24
-#define DT_INIT_ARRAY 25
-#define DT_FINI_ARRAY 26
-#define DT_INIT_ARRAYSZ 27
-#define DT_FINI_ARRAYSZ 28
-#define DT_RUNPATH 29
-#define DT_FLAGS 30
-/* glibc and BSD disagree for DT_ENCODING; glibc looks wrong. */
-#define DT_PREINIT_ARRAY 32
-#define DT_PREINIT_ARRAYSZ 33
-#define DT_RELRSZ 35
-#define DT_RELR 36
-#define DT_RELRENT 37
-
-#define DT_GNU_HASH 0x6ffffef5
-#define DT_TLSDESC_PLT 0x6ffffef6
-#define DT_TLSDESC_GOT 0x6ffffef7
-
-/* http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
-#define EI_ABIVERSION 8
-#undef EI_PAD
-#define EI_PAD 9
-
-/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
-#define ELFCOMPRESS_ZLIB 1
-#define ELFCOMPRESS_LOOS 0x60000000
-#define ELFCOMPRESS_HIOS 0x6fffffff
-#define ELFCOMPRESS_LOPROC 0x70000000
-#define ELFCOMPRESS_HIPROC 0x7fffffff
/* http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
#define ELFOSABI_SYSV 0 /* Synonym for ELFOSABI_NONE used by valgrind. */
-#define ELFOSABI_HPUX 1
-#define ELFOSABI_NETBSD 2
#define ELFOSABI_GNU 3 /* Synonym for ELFOSABI_LINUX. */
-#define ELFOSABI_SOLARIS 6
-#define ELFOSABI_AIX 7
-#define ELFOSABI_IRIX 8
-#define ELFOSABI_FREEBSD 9
-#define ELFOSABI_TRU64 10
-#define ELFOSABI_MODESTO 11
-#define ELFOSABI_OPENBSD 12
-#define ELFOSABI_OPENVMS 13
-#define ELFOSABI_NSK 14
-#define ELFOSABI_AROS 15
-#define ELFOSABI_FENIXOS 16
-#define ELFOSABI_CLOUDABI 17
-#define ELFOSABI_OPENVOS 18
-#define ELFOSABI_ARM_AEABI 64
/* http://www.sco.com/developers/gabi/latest/ch4.reloc.html */
#define ELF32_R_INFO(sym, type) ((((Elf32_Word)sym) << 8) | ((type) & 0xff))
@@ -294,236 +217,17 @@
#define ELF32_ST_INFO(b,t) ELF_ST_INFO(b,t)
#define ELF64_ST_INFO(b,t) ELF_ST_INFO(b,t)
-/* http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
-#define EM_S370 9
-#define EM_VPP500 17
-#define EM_960 19
-#define EM_V800 36
-#define EM_FR20 37
-#define EM_RH32 38
-#define EM_RCE 39
-#define EM_FAKE_ALPHA 41
-#define EM_TRICORE 44
-#define EM_ARC 45
-#define EM_H8_300H 47
-#define EM_H8S 48
-#define EM_H8_500 49
-#define EM_MIPS_X 51
-#define EM_COLDFIRE 52
-#define EM_68HC12 53
-#define EM_MMA 54
-#define EM_PCP 55
-#define EM_NCPU 56
-#define EM_NDR1 57
-#define EM_STARCORE 58
-#define EM_ME16 59
-#define EM_ST100 60
-#define EM_TINYJ 61
-#define EM_PDSP 63
-#define EM_PDP10 64
-#define EM_PDP11 65
-#define EM_FX66 66
-#define EM_ST9PLUS 67
-#define EM_ST7 68
-#define EM_68HC16 69
-#define EM_68HC11 70
-#define EM_68HC08 71
-#define EM_68HC05 72
-#define EM_SVX 73
-#define EM_ST19 74
-#define EM_VAX 75
-#define EM_JAVELIN 77
-#define EM_FIREPATH 78
-#define EM_ZSP 79
-#define EM_MMIX 80
-#define EM_HUANY 81
-#define EM_PRISM 82
-#define EM_AVR 83
-#define EM_FR30 84
-#define EM_D10V 85
-#define EM_D30V 86
-#define EM_V850 87
-#define EM_MN10200 90
-#define EM_PJ 91
-#define EM_ARC_COMPACT 93
-#define EM_XTENSA 94
-#define EM_VIDEOCORE 95
-#define EM_TMM_GPP 96
-#define EM_NS32K 97
-#define EM_TPC 98
-#define EM_SNP1K 99
-#define EM_ST200 100
-#define EM_IP2K 101
-#define EM_MAX 102
-#define EM_CR 103
-#define EM_F2MC16 104
-#define EM_MSP430 105
-#define EM_SE_C33 107
-#define EM_SEP 108
-#define EM_ARCA 109
-#define EM_UNICORE 110
-#define EM_EXCESS 111
-#define EM_DXP 112
-#define EM_CRX 114
-#define EM_XGATE 115
-#define EM_C166 116
-#define EM_M16C 117
-#define EM_DSPIC30F 118
-#define EM_CE 119
-#define EM_M32C 120
-#define EM_TSK3000 131
-#define EM_RS08 132
-#define EM_SHARC 133
-#define EM_ECOG2 134
-#define EM_SCORE7 135
-#define EM_DSP24 136
-#define EM_VIDEOCORE3 137
-#define EM_LATTICEMICO32 138
-#define EM_SE_C17 139
-#define EM_TI_C2000 141
-#define EM_TI_C5500 142
-#define EM_MMDSP_PLUS 160
-#define EM_CYPRESS_M8C 161
-#define EM_R32C 162
-#define EM_TRIMEDIA 163
-#define EM_QDSP6 164
-#define EM_8051 165
-#define EM_STXP7X 166
-#define EM_NDS32 167
-#define EM_ECOG1 168
-#define EM_ECOG1X 168
-#define EM_MAXQ30 169
-#define EM_XIMO16 170
-#define EM_MANIK 171
-#define EM_CRAYNV2 172
-#define EM_RX 173
-#define EM_METAG 174
-#define EM_MCST_ELBRUS 175
-#define EM_ECOG16 176
-#define EM_CR16 177
-#define EM_ETPU 178
-#define EM_SLE9X 179
-#define EM_L10M 180
-#define EM_K10M 181
-#define EM_AVR32 185
-#define EM_STM8 186
-#define EM_TILE64 187
-#define EM_CUDA 190
-#define EM_CLOUDSHIELD 192
-#define EM_COREA_1ST 193
-#define EM_COREA_2ND 194
-#define EM_ARC_COMPACT2 195
-#define EM_OPEN8 196
-#define EM_RL78 197
-#define EM_VIDEOCORE5 198
-#define EM_78KOR 199
-#define EM_56800EX 200
-#define EM_BA1 201
-#define EM_BA2 202
-#define EM_XCORE 203
-#define EM_MCHP_PIC 204
-#define EM_INTEL205 205
-#define EM_INTEL206 206
-#define EM_INTEL207 207
-#define EM_INTEL208 208
-#define EM_INTEL209 209
-#define EM_KM32 210
-#define EM_KMX32 211
-#define EM_KMX16 212
-#define EM_KMX8 213
-#define EM_KVARC 214
-#define EM_CDP 215
-#define EM_COGE 216
-#define EM_COOL 217
-#define EM_NORC 218
-#define EM_CSR_KALIMBA 219
-#define EM_Z80 220
-#define EM_VISIUM 221
-#define EM_FT32 222
-#define EM_MOXIE 223
-#define EM_AMDGPU 224
-#define EM_RISCV 243
-
-/* http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
-#define ET_LOOS 0xfe00
-#define ET_HIOS 0xfeff
-
/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
-#define GRP_COMDAT 0x1
#define GRP_MASKOS 0x0ff00000
#define GRP_MASKPROC 0xf0000000
-/* http://www.sco.com/developers/gabi/latest/ch5.pheader.html */
-#define PF_X 0x1
-#define PF_W 0x2
-#define PF_R 0x4
-#define PF_MASKOS 0x0ff00000
-#define PF_MASKPROC 0xf0000000
-
-#define PT_GNU_RELRO 0x6474e552
-
-#define STB_LOOS 10
-#define STB_HIOS 12
-#define STB_LOPROC 13
-#define STB_HIPROC 15
-
/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
-#define SHF_MERGE 0x10
-#define SHF_STRINGS 0x20
-#define SHF_INFO_LINK 0x40
-#define SHF_LINK_ORDER 0x80
-#define SHF_OS_NONCONFORMING 0x100
-#define SHF_GROUP 0x200
-#define SHF_TLS 0x400
-#define SHF_COMPRESSED 0x800
-#define SHF_MASKOS 0x0ff00000
-#define SHF_MASKPROC 0xf0000000
-
-/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
-#define SHN_LOOS 0xff20
-#define SHN_HIOS 0xff3f
-#define SHN_XINDEX 0xffff
-
-/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html */
-#define SHT_INIT_ARRAY 14
-#define SHT_FINI_ARRAY 15
-#define SHT_PREINIT_ARRAY 16
-#define SHT_GROUP 17
-#define SHT_SYMTAB_SHNDX 18
+/*
+ * Standard replacement for SHT_ANDROID_RELR.
+ */
#define SHT_RELR 19
#undef SHT_NUM
#define SHT_NUM 20
-#define SHT_LOOS 0x60000000
-#define SHT_HIOS 0x6fffffff
-
-/* http://www.sco.com/developers/gabi/latest/ch4.symtab.html */
-#define STN_UNDEF 0
-
-/* http://www.sco.com/developers/gabi/latest/ch4.symtab.html */
-#define STT_GNU_IFUNC 10
-#define STT_LOOS 10
-#define STT_HIOS 12
-#define STT_LOPROC 13
-#define STT_HIPROC 15
-
-/* http://www.sco.com/developers/gabi/latest/ch4.symtab.html */
-#define STV_DEFAULT 0
-#define STV_INTERNAL 1
-#define STV_HIDDEN 2
-#define STV_PROTECTED 3
-
-/* The kernel uses NT_PRFPREG but glibc also offers NT_FPREGSET */
-#define NT_FPREGSET NT_PRFPREG
-
-#define ELF_NOTE_GNU "GNU"
-
-#define NT_GNU_BUILD_ID 3
-
-#define VER_FLG_BASE 0x1
-#define VER_FLG_WEAK 0x2
-
-#define VER_NDX_LOCAL 0
-#define VER_NDX_GLOBAL 1
/*
* Experimental support for SHT_RELR sections. For details, see proposal
@@ -553,3 +257,13 @@
#define DT_ANDROID_RELSZ 0x60000010 // DT_LOOS + 3
#define DT_ANDROID_RELA 0x60000011 // DT_LOOS + 4
#define DT_ANDROID_RELASZ 0x60000012 // DT_LOOS + 5
+
+/* Linux traditionally doesn't have the trailing 64 that BSD has on these. */
+#define R_AARCH64_TLS_DTPREL R_AARCH64_TLS_DTPREL64
+#define R_AARCH64_TLS_DTPMOD R_AARCH64_TLS_DTPMOD64
+#define R_AARCH64_TLS_TPREL R_AARCH64_TLS_TPREL64
+
+/* TODO: upstream these to FreeBSD? */
+#define R_ARM_TLS_DESC 13
+#define R_ARM_IRELATIVE 160
+#define R_X86_64_JUMP_SLOT 7
diff --git a/libc/include/fenv.h b/libc/include/fenv.h
index 7b775b6..3fd9852 100644
--- a/libc/include/fenv.h
+++ b/libc/include/fenv.h
@@ -35,6 +35,8 @@
#include <bits/fenv_arm.h>
#elif defined(__i386__)
#include <bits/fenv_x86.h>
+#elif defined(__riscv)
+#include <bits/fenv_riscv64.h>
#elif defined(__x86_64__)
#include <bits/fenv_x86_64.h>
#endif
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index 3a64b33..a3de9c7 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -37,8 +37,12 @@
* @(#)setjmp.h 8.2 (Berkeley) 1/21/94
*/
-#ifndef _SETJMP_H_
-#define _SETJMP_H_
+#pragma once
+
+/**
+ * @file setjmp.h
+ * @brief Non-local jumps.
+ */
#include <sys/cdefs.h>
@@ -48,28 +52,60 @@
#define _JBLEN 64
#elif defined(__i386__)
#define _JBLEN 10
+#elif defined(__riscv)
+#define _JBLEN 29
#elif defined(__x86_64__)
#define _JBLEN 11
#endif
+/** The type of the buffer used by sigsetjmp()/siglongjmp(). */
typedef long sigjmp_buf[_JBLEN + 1];
+
+/** The type of the buffer used by setjmp()/longjmp(). */
typedef long jmp_buf[_JBLEN];
#undef _JBLEN
__BEGIN_DECLS
+/**
+ * Equivalent to sigsetjmp() with the second argument 0, so that the signal
+ * mask is not saved.
+ */
int _setjmp(jmp_buf __env) __returns_twice;
+
+/** Equivalent to siglongjmp(). */
__noreturn void _longjmp(jmp_buf __env, int __value);
+/**
+ * Equivalent to sigsetjmp() with the second argument 1, so that the signal
+ * mask is saved.
+ */
int setjmp(jmp_buf __env) __returns_twice;
-__noreturn void longjmp(jmp_buf __env, int __value);
+/** C11 says setjmp() must be a macro, but Android already had a function. */
#define setjmp(__env) setjmp(__env)
-int sigsetjmp(sigjmp_buf __env, int __save_signal_mask);
+/** Equivalent to siglongjmp(). */
+__noreturn void longjmp(jmp_buf __env, int __value);
+
+/**
+ * [sigsetjmp(3)](http://man7.org/linux/man-pages/man3/sigsetjmp.3.html)
+ * sets the target of a future siglongjmp() call, saving or not saving the
+ * current signal mask based on the second argument.
+ *
+ * Returns 0 when first called, and returns the value passed to siglongjmp()
+ * when returning here as a result of a siglongjmp() call.
+ */
+int sigsetjmp(sigjmp_buf __env, int __save_signal_mask) __returns_twice;
+
+/**
+ * [siglongjmp(3)](http://man7.org/linux/man-pages/man3/siglongjmp.3.html)
+ * transfers control back to the site of the sigsetjmp() call that initialized
+ * the given jump buffer, returning the given value.
+ *
+ * Does not return.
+ */
__noreturn void siglongjmp(sigjmp_buf __env, int __value);
__END_DECLS
-
-#endif
diff --git a/libc/include/stdio_ext.h b/libc/include/stdio_ext.h
index 3aa183d..eda5919 100644
--- a/libc/include/stdio_ext.h
+++ b/libc/include/stdio_ext.h
@@ -96,13 +96,21 @@
/**
* [__fpending(3)](http://man7.org/linux/man-pages/man3/__fpending.3.html) returns the number of
- * bytes in the output buffer.
+ * bytes in the output buffer. See __freadahead() for the input buffer.
*
* Available since API level 23.
*/
size_t __fpending(FILE* __fp) __INTRODUCED_IN(23);
/**
+ * __freadahead(3) returns the number of bytes in the input buffer.
+ * See __fpending() for the output buffer.
+ *
+ * Available since API level 34.
+ */
+size_t __freadahead(FILE* __fp) __INTRODUCED_IN(34);
+
+/**
* [_flushlbf(3)](http://man7.org/linux/man-pages/man3/_flushlbf.3.html) flushes all
* line-buffered streams.
*
diff --git a/libc/include/string.h b/libc/include/string.h
index 0cc5611..59c4687 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -55,7 +55,24 @@
void* mempcpy(void* __dst, const void* __src, size_t __n) __INTRODUCED_IN(23);
#endif
void* memmove(void* __dst, const void* __src, size_t __n);
+
+/**
+ * [memset(3)](http://man7.org/linux/man-pages/man3/memset.3.html) writes the
+ * bottom 8 bits of the given int to the next `n` bytes of `dst`.
+ *
+ * Returns `dst`.
+ */
void* memset(void* __dst, int __ch, size_t __n);
+
+/**
+ * [memset_explicit(3)](http://man7.org/linux/man-pages/man3/memset_explicit.3.html)
+ * writes the bottom 8 bits of the given int to the next `n` bytes of `dst`,
+ * but won't be optimized out by the compiler.
+ *
+ * Returns `dst`.
+ */
+void* memset_explicit(void* __dst, int __ch, size_t __n) __INTRODUCED_IN(34);
+
void* memmem(const void* __haystack, size_t __haystack_size, const void* __needle, size_t __needle_size) __attribute_pure__;
char* strchr(const char* __s, int __ch) __attribute_pure__;
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 6ef0c12..9e865a3 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -168,8 +168,13 @@
* PID file descriptor.
*
* Returns the number of bytes advised on success, and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 31. Its sibling process_mrelease() does not have a
+ * libc wrapper and should be called using syscall() instead. Given the lack of
+ * widespread applicability of this system call and the absence of wrappers in
+ * other libcs, it was probably a mistake to have added this wrapper to bionic.
*/
-ssize_t process_madvise(int __pid_fd, const struct iovec* __iov, size_t __count, int __advice, unsigned __flags);
+ssize_t process_madvise(int __pid_fd, const struct iovec* __iov, size_t __count, int __advice, unsigned __flags) __INTRODUCED_IN(31);
#if defined(__USE_GNU)
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 4184f6c..623631e 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -40,7 +40,7 @@
__BEGIN_DECLS
-#if defined(__aarch64__)
+#if defined(__aarch64__) || defined(__riscv)
#define __STAT64_BODY \
dev_t st_dev; \
ino_t st_ino; \
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index 9c5801f..72b8adb 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _SYS_UCONTEXT_H_
-#define _SYS_UCONTEXT_H_
+#pragma once
#include <sys/cdefs.h>
@@ -313,8 +312,66 @@
struct _libc_fpstate __fpregs_mem;
} ucontext_t;
+#elif defined(__riscv)
+
+#define NGREG 32
+
+#define REG_PC 0
+#define REG_RA 1
+#define REG_SP 2
+#define REG_TP 4
+#define REG_S0 8
+#define REG_A0 10
+
+typedef unsigned long __riscv_mc_gp_state[NGREG];
+
+typedef unsigned long greg_t;
+typedef unsigned long gregset_t[NGREG];
+typedef union __riscv_mc_fp_state fpregset_t;
+
+/* These match the kernel <asm/ptrace.h> types but with different names. */
+
+struct __riscv_mc_f_ext_state {
+ uint32_t __f[32];
+ uint32_t __fcsr;
+};
+
+struct __riscv_mc_d_ext_state {
+ uint64_t __f[32];
+ uint32_t __fcsr;
+};
+
+struct __riscv_mc_q_ext_state {
+ uint64_t __f[64] __attribute__((__aligned__(16)));
+ uint32_t __fcsr;
+ uint32_t __reserved[3];
+};
+
+union __riscv_mc_fp_state {
+ struct __riscv_mc_f_ext_state __f;
+ struct __riscv_mc_d_ext_state __d;
+ struct __riscv_mc_q_ext_state __q;
+};
+
+/* This matches the kernel <asm/sigcontext.h> but with different names. */
+
+typedef struct mcontext_t {
+ __riscv_mc_gp_state __gregs;
+ union __riscv_mc_fp_state __fpregs;
+} mcontext_t;
+
+/* This matches the kernel <asm/ucontext.h> but using mcontext_t. */
+
+typedef struct ucontext_t {
+ unsigned long uc_flags;
+ struct ucontext_t* uc_link;
+ stack_t uc_stack;
+ sigset_t uc_sigmask;
+ /* The kernel adds extra padding here to allow sigset_t to grow. */
+ char __padding[128 - sizeof(sigset_t)];
+ mcontext_t uc_mcontext;
+} ucontext_t;
+
#endif
__END_DECLS
-
-#endif /* _SYS_UCONTEXT_H_ */
diff --git a/libc/include/sys/user.h b/libc/include/sys/user.h
index 2392edd..432c7cb 100644
--- a/libc/include/sys/user.h
+++ b/libc/include/sys/user.h
@@ -26,8 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef _SYS_USER_H_
-#define _SYS_USER_H_
+#pragma once
#include <sys/cdefs.h>
#include <stddef.h> /* For size_t. */
@@ -233,6 +232,11 @@
uint32_t fpcr;
};
+#elif defined(__riscv)
+
+// This space deliberately left blank for now.
+// No other libcs have any riscv64-specific structs.
+
#else
#error "Unsupported architecture."
@@ -240,5 +244,3 @@
#endif
__END_DECLS
-
-#endif /* _SYS_USER_H_ */
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index e360421..b5694b8 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -313,10 +313,37 @@
int getdomainname(char* __buf, size_t __buf_size) __INTRODUCED_IN(26);
int setdomainname(const char* __name, size_t __n) __INTRODUCED_IN(26);
+/**
+ * [copy_file_range(2)](https://man7.org/linux/man-pages/man2/copy_file_range.2.html) copies
+ * a range of data from one file descriptor to another.
+ *
+ * Returns the number of bytes copied on success, and returns -1 and sets errno
+ * on failure.
+ *
+ * Available since API level 34.
+ */
+ssize_t copy_file_range(int __fd_in, off64_t* __off_in, int __fd_out, off64_t* __off_out, size_t __length, unsigned int __flags) __INTRODUCED_IN(34);
+
#if __ANDROID_API__ >= 28
void swab(const void* __src, void* __dst, ssize_t __byte_count) __INTRODUCED_IN(28);
#endif
+/**
+ * [close_range(2)](https://man7.org/linux/man-pages/man2/close_range.2.html)
+ * performs an action (which depends on value of flags) on an inclusive range
+ * of file descriptors.
+ *
+ * Available since API level 34.
+ *
+ * Note: there is no emulation on too old kernels, hence this will fail with
+ * -1/ENOSYS on pre-5.9 kernels, -1/EINVAL for unsupported flags. In particular
+ * CLOSE_RANGE_CLOEXEC requires 5.11, though support was backported to Android
+ * Common Kernel 5.10-T.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ */
+int close_range(unsigned int __min_fd, unsigned int __max_fd, int __flags) __INTRODUCED_IN(34);
+
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
#define _UNISTD_H_
#include <bits/fortify/unistd.h>
diff --git a/libc/kernel/README.md b/libc/kernel/README.md
index 5f1c81d..3846a4f 100644
--- a/libc/kernel/README.md
+++ b/libc/kernel/README.md
@@ -99,6 +99,7 @@
Run this command to automatically download the latest version of the headers
and import them if there is no checked out kernel source tree:
```
+ # For testing only, not for use in production!
bionic/libc/kernel/tools/generate_uapi_headers.sh --download-kernel
```
diff --git a/libc/kernel/android/BUILD b/libc/kernel/android/BUILD
new file mode 100644
index 0000000..b862a6d
--- /dev/null
+++ b/libc/kernel/android/BUILD
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Android Open Source Project
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+load("//build/bazel/rules/apis:cc_api_contribution.bzl", "cc_api_headers")
+
+package(default_visibility = ["//bionic/libc:__pkg__"])
+
+cc_api_headers(
+ name="libc_kernel_android_uapi_headers",
+ include_dir="uapi",
+ hdrs=glob(["uapi/**/*.h"]),
+ system=True,
+)
+
+cc_api_headers(
+ name="libc_kernel_android_scsi_headers",
+ include_dir="scsi",
+ hdrs=glob(["scsi/**/*.h"]),
+ system=True,
+)
diff --git a/libc/kernel/android/scsi/scsi/scsi_proto.h b/libc/kernel/android/scsi/scsi/scsi_proto.h
index eea87a0..13ac4c8 100644
--- a/libc/kernel/android/scsi/scsi/scsi_proto.h
+++ b/libc/kernel/android/scsi/scsi/scsi_proto.h
@@ -183,6 +183,8 @@
ZBC_ZONE_TYPE_CONV = 0x1,
ZBC_ZONE_TYPE_SEQWRITE_REQ = 0x2,
ZBC_ZONE_TYPE_SEQWRITE_PREF = 0x3,
+ ZBC_ZONE_TYPE_SEQ_OR_BEFORE_REQ = 0x4,
+ ZBC_ZONE_TYPE_GAP = 0x5,
};
enum zbc_zone_cond {
ZBC_ZONE_COND_NO_WP = 0x0,
@@ -194,6 +196,10 @@
ZBC_ZONE_COND_FULL = 0xe,
ZBC_ZONE_COND_OFFLINE = 0xf,
};
+enum zbc_zone_alignment_method {
+ ZBC_CONSTANT_ZONE_LENGTH = 0x1,
+ ZBC_CONSTANT_ZONE_START_OFFSET = 0x8,
+};
enum scsi_version_descriptor {
SCSI_VERSION_DESCRIPTOR_FCP4 = 0x0a40,
SCSI_VERSION_DESCRIPTOR_ISCSI = 0x0960,
diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py
index cfd301a..f15fab4 100755
--- a/libc/kernel/tools/clean_header.py
+++ b/libc/kernel/tools/clean_header.py
@@ -109,9 +109,6 @@
if arch and arch in kernel_default_arch_macros:
macros.update(kernel_default_arch_macros[arch])
- if arch and arch in kernel_arch_token_replacements:
- blocks.replaceTokens(kernel_arch_token_replacements[arch])
-
blocks.removeStructs(kernel_structs_to_remove)
blocks.optimizeMacros(macros)
blocks.optimizeIf01()
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 26121ca..40e1f26 100755
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -14,7 +14,7 @@
utils.panic('ANDROID_BUILD_TOP not set.\n')
# Set up the env vars for libclang.
-site.addsitedir(os.path.join(top, 'prebuilts/clang/host/linux-x86/clang-stable/lib64/python3/site-packages/'))
+site.addsitedir(os.path.join(top, 'prebuilts/clang/host/linux-x86/clang-stable/lib/python3/site-packages/'))
import clang.cindex
from clang.cindex import conf
@@ -28,7 +28,7 @@
# Set up LD_LIBRARY_PATH to include libclang.so, libLLVM.so, and etc.
# Note that setting LD_LIBRARY_PATH with os.putenv() sometimes doesn't help.
-clang.cindex.Config.set_library_file(os.path.join(top, 'prebuilts/clang/host/linux-x86/clang-stable/lib64/libclang.so'))
+clang.cindex.Config.set_library_file(os.path.join(top, 'prebuilts/clang/host/linux-x86/clang-stable/lib/libclang.so'))
from defaults import *
@@ -155,6 +155,11 @@
pass
+class UnparseableStruct(Exception):
+ """An exception that will be raised for structs that cannot be parsed."""
+ pass
+
+
# The __contains__ function in libclang SourceRange class contains a bug. It
# gives wrong result when dealing with single line range.
# Bug filed with upstream:
@@ -1197,22 +1202,38 @@
def removeStructs(self, structs):
"""Remove structs."""
- for b in self.blocks:
+ extra_includes = []
+ block_num = 0
+ num_blocks = len(self.blocks)
+ while block_num < num_blocks:
+ b = self.blocks[block_num]
+ block_num += 1
# Have to look in each block for a top-level struct definition.
if b.directive:
continue
num_tokens = len(b.tokens)
- # A struct definition has at least 5 tokens:
+ # A struct definition usually looks like:
# struct
# ident
# {
# }
# ;
- if num_tokens < 5:
+ # However, the structure might be spread across multiple blocks
+ # if the structure looks like this:
+ # struct ident
+ # {
+ # #ifdef VARIABLE
+ # pid_t pid;
+ # #endif
+ # }:
+ # So the total number of tokens in the block might be less than
+ # five but assume at least three.
+ if num_tokens < 3:
continue
+
# This is a simple struct finder, it might fail if a top-level
# structure has an #if type directives that confuses the algorithm
- # for finding th end of the structure. Or if there is another
+ # for finding the end of the structure. Or if there is another
# structure definition embedded in the structure.
i = 0
while i < num_tokens - 2:
@@ -1223,24 +1244,58 @@
if (b.tokens[i + 1].kind == TokenKind.IDENTIFIER and
b.tokens[i + 2].kind == TokenKind.PUNCTUATION and
b.tokens[i + 2].id == "{" and b.tokens[i + 1].id in structs):
+ # Add an include for the structure to be removed of the form:
+ # #include <bits/STRUCT_NAME.h>
+ struct_token = b.tokens[i + 1]
+ if not structs[struct_token.id]:
+ extra_includes.append("<bits/%s.h>" % struct_token.id)
+
# Search forward for the end of the structure.
- # Very simple search, look for } and ; tokens. If something
- # more complicated is needed we can add it later.
+ # Very simple search, look for } and ; tokens.
+ # If we hit the end of the block, we'll need to start
+ # looking at the next block.
j = i + 3
- while j < num_tokens - 1:
- if (b.tokens[j].kind == TokenKind.PUNCTUATION and
- b.tokens[j].id == "}" and
- b.tokens[j + 1].kind == TokenKind.PUNCTUATION and
- b.tokens[j + 1].id == ";"):
- b.tokens = b.tokens[0:i] + b.tokens[j + 2:num_tokens]
+ depth = 1
+ struct_removed = False
+ while not struct_removed:
+ while j < num_tokens:
+ if b.tokens[j].kind == TokenKind.PUNCTUATION:
+ if b.tokens[j].id == '{':
+ depth += 1
+ elif b.tokens[j].id == '}':
+ depth -= 1
+ elif b.tokens[j].id == ';' and depth == 0:
+ b.tokens = b.tokens[0:i] + b.tokens[j + 1:num_tokens]
+ num_tokens = len(b.tokens)
+ struct_removed = True
+ break
+ j += 1
+ if not struct_removed:
+ b.tokens = b.tokens[0:i]
+
+ # Skip directive blocks.
+ start_block = block_num
+ while block_num < num_blocks:
+ if not self.blocks[block_num].directive:
+ break
+ block_num += 1
+ if block_num >= num_blocks:
+ # Unparsable struct, error out.
+ raise UnparseableStruct("Cannot remove struct %s: %s" % (struct_token.id, struct_token.location))
+ self.blocks = self.blocks[0:start_block] + self.blocks[block_num:num_blocks]
+ num_blocks = len(self.blocks)
+ b = self.blocks[start_block]
+ block_num = start_block + 1
num_tokens = len(b.tokens)
- j = i
- break
- j += 1
- i = j
+ i = 0
+ j = 0
continue
i += 1
+ for extra_include in extra_includes:
+ replacement = CppStringTokenizer(extra_include)
+ self.blocks.insert(2, Block(replacement.tokens, directive='include'))
+
def optimizeAll(self, macros):
self.optimizeMacros(macros)
self.optimizeIf01()
@@ -1404,35 +1459,12 @@
def replaceTokens(self, replacements):
"""Replace tokens according to the given dict."""
- extra_includes = []
for b in self.blocks:
made_change = False
if b.isInclude() is None:
i = 0
while i < len(b.tokens):
tok = b.tokens[i]
- if (tok.kind == TokenKind.KEYWORD and tok.id == 'struct'
- and (i + 2) < len(b.tokens) and b.tokens[i + 2].id == '{'):
- struct_name = b.tokens[i + 1].id
- if struct_name in kernel_struct_replacements:
- extra_includes.append("<bits/%s.h>" % struct_name)
- end = i + 2
- depth = 1
- while end < len(b.tokens) and depth > 0:
- if b.tokens[end].id == '}':
- depth -= 1
- elif b.tokens[end].id == '{':
- depth += 1
- end += 1
- end += 1 # Swallow last '}'
- while end < len(b.tokens) and b.tokens[end].id != ';':
- end += 1
- end += 1 # Swallow ';'
- # Remove these tokens. We'll replace them later with a #include block.
- b.tokens[i:end] = []
- made_change = True
- # We've just modified b.tokens, so revisit the current offset.
- continue
if tok.kind == TokenKind.IDENTIFIER:
if tok.id in replacements:
tok.id = replacements[tok.id]
@@ -1447,10 +1479,6 @@
# Keep 'expr' in sync with 'tokens'.
b.expr = CppExpr(b.tokens)
- for extra_include in extra_includes:
- replacement = CppStringTokenizer(extra_include)
- self.blocks.insert(2, Block(replacement.tokens, directive='include'))
-
def strip_space(s):
@@ -1647,7 +1675,7 @@
def get_blocks(self, lines):
blocks = BlockParser().parse(CppStringTokenizer('\n'.join(lines)))
- return map(lambda a: str(a), blocks)
+ return list(map(lambda a: str(a), blocks))
def test_hash(self):
self.assertEqual(self.get_blocks(["#error hello"]), ["#error hello"])
@@ -2020,7 +2048,7 @@
struct timeval val2;
};
"""
- self.assertEqual(self.parse(text, set(["remove"])), expected)
+ self.assertEqual(self.parse(text, {"remove": True}), expected)
def test_remove_struct_from_end(self):
text = """\
@@ -2039,7 +2067,7 @@
struct timeval val2;
};
"""
- self.assertEqual(self.parse(text, set(["remove"])), expected)
+ self.assertEqual(self.parse(text, {"remove": True}), expected)
def test_remove_minimal_struct(self):
text = """\
@@ -2047,7 +2075,7 @@
};
"""
expected = "";
- self.assertEqual(self.parse(text, set(["remove"])), expected)
+ self.assertEqual(self.parse(text, {"remove": True}), expected)
def test_remove_struct_with_struct_fields(self):
text = """\
@@ -2067,7 +2095,7 @@
struct remove val2;
};
"""
- self.assertEqual(self.parse(text, set(["remove"])), expected)
+ self.assertEqual(self.parse(text, {"remove": True}), expected)
def test_remove_consecutive_structs(self):
text = """\
@@ -2099,7 +2127,7 @@
struct timeval val2;
};
"""
- self.assertEqual(self.parse(text, set(["remove1", "remove2"])), expected)
+ self.assertEqual(self.parse(text, {"remove1": True, "remove2": True}), expected)
def test_remove_multiple_structs(self):
text = """\
@@ -2132,7 +2160,101 @@
int val;
};
"""
- self.assertEqual(self.parse(text, set(["remove1", "remove2"])), expected)
+ self.assertEqual(self.parse(text, {"remove1": True, "remove2": True}), expected)
+
+ def test_remove_struct_with_inline_structs(self):
+ text = """\
+struct remove {
+ int val1;
+ int val2;
+ struct {
+ int val1;
+ struct {
+ int val1;
+ } level2;
+ } level1;
+};
+struct something {
+ struct timeval val1;
+ struct timeval val2;
+};
+"""
+ expected = """\
+struct something {
+ struct timeval val1;
+ struct timeval val2;
+};
+"""
+ self.assertEqual(self.parse(text, {"remove": True}), expected)
+
+ def test_remove_struct_across_blocks(self):
+ text = """\
+struct remove {
+ int val1;
+ int val2;
+#ifdef PARAMETER1
+ PARAMETER1
+#endif
+#ifdef PARAMETER2
+ PARAMETER2
+#endif
+};
+struct something {
+ struct timeval val1;
+ struct timeval val2;
+};
+"""
+ expected = """\
+struct something {
+ struct timeval val1;
+ struct timeval val2;
+};
+"""
+ self.assertEqual(self.parse(text, {"remove": True}), expected)
+
+ def test_remove_struct_across_blocks_multiple_structs(self):
+ text = """\
+struct remove1 {
+ int val1;
+ int val2;
+#ifdef PARAMETER1
+ PARAMETER1
+#endif
+#ifdef PARAMETER2
+ PARAMETER2
+#endif
+};
+struct remove2 {
+};
+struct something {
+ struct timeval val1;
+ struct timeval val2;
+};
+"""
+ expected = """\
+struct something {
+ struct timeval val1;
+ struct timeval val2;
+};
+"""
+ self.assertEqual(self.parse(text, {"remove1": True, "remove2": True}), expected)
+
+ def test_remove_multiple_struct_and_add_includes(self):
+ text = """\
+struct remove1 {
+ int val1;
+ int val2;
+};
+struct remove2 {
+ struct timeval val1;
+ struct timeval val2;
+};
+"""
+ expected = """\
+#include <bits/remove1.h>
+#include <bits/remove2.h>
+"""
+ self.assertEqual(self.parse(text, {"remove1": False, "remove2": False}), expected)
class FullPathTest(unittest.TestCase):
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 2089285..abb8f82 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -5,9 +5,6 @@
import time, os, sys
from utils import *
-# the list of supported architectures
-kernel_archs = [ 'arm', 'arm64', 'x86' ]
-
# the list of include directories that belong to the kernel
# tree. used when looking for sources...
kernel_dirs = [ "linux", "asm", "asm-generic", "mtd" ]
@@ -35,34 +32,34 @@
"__kernel_old_timeval": "1",
}
-# this is the set of known kernel data structures we want to remove from
-# the final headers
-kernel_structs_to_remove = set(
- [
- # Remove the structures since they are still the same as
- # timeval, itimerval.
- "__kernel_old_timeval",
- "__kernel_old_itimerval",
- ]
- )
+# This is the set of known kernel data structures we want to remove from
+# the final headers. If the map value is False, that means that in
+# addition to removing the structure, add an #include <bits/STRUCT.h>
+# to the file.
+kernel_structs_to_remove = {
+ # Remove the structures since they are still the same as
+ # timeval, itimerval.
+ "__kernel_old_timeval": True,
+ "__kernel_old_itimerval": True,
+ # Replace all of the below structures with #include <bits/STRUCT.h>
+ "epoll_event": False,
+ "flock": False,
+ "flock64": False,
+ "in_addr": False,
+ "ip_mreq_source": False,
+ "ip_msfilter": False,
+ }
# define to true if you want to remove all defined(CONFIG_FOO) tests
# from the clean headers. testing shows that this is not strictly necessary
# but just generates cleaner results
kernel_remove_config_macros = True
-# maps an architecture to a set of default macros that would be provided by
-# toolchain preprocessor
+# Maps an architecture to a set of default macros that would be provided by
+# the toolchain's preprocessor. Currently only used to remove confusing
+# big-endian junk from the 32-bit arm headers.
kernel_default_arch_macros = {
"arm": {"__ARMEB__": kCppUndefinedMacro, "__ARM_EABI__": "1"},
- "arm64": {},
- "x86": {},
- }
-
-kernel_arch_token_replacements = {
- "arm": {},
- "arm64": {},
- "x86": {},
}
# Replace tokens in the output according to this mapping.
@@ -100,20 +97,6 @@
}
-# This is the set of struct definitions that we want to replace with
-# a #include of <bits/struct.h> instead.
-kernel_struct_replacements = set(
- [
- "epoll_event",
- "flock",
- "flock64",
- "in_addr",
- "ip_mreq_source",
- "ip_msfilter",
- ]
- )
-
-
# This is the set of known static inline functions that we want to keep
# in the final kernel headers.
kernel_known_generic_statics = set(
diff --git a/libc/kernel/tools/generate_uapi_headers.sh b/libc/kernel/tools/generate_uapi_headers.sh
index 7e49cde..12f60e5 100755
--- a/libc/kernel/tools/generate_uapi_headers.sh
+++ b/libc/kernel/tools/generate_uapi_headers.sh
@@ -43,7 +43,7 @@
ANDROID_KERNEL_BRANCH="android-mainline"
KERNEL_DIR=""
KERNEL_DOWNLOAD=0
-ARCH_LIST=("arm" "arm64" "x86")
+ARCH_LIST=("arm" "arm64" "riscv" "x86")
ANDROID_KERNEL_DIR="external/kernel-headers/original"
SKIP_GENERATION=0
VERIFY_HEADERS_ONLY=0
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index f2e78da..abc72a4 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -27,8 +27,14 @@
def ProcessFiles(updater, original_dir, modified_dir, src_rel_dir, update_rel_dir):
# Delete the old headers before updating to the new headers.
update_dir = os.path.join(get_kernel_dir(), update_rel_dir)
- shutil.rmtree(update_dir)
- os.mkdir(update_dir, 0o755)
+ for root, dirs, files in os.walk(update_dir, topdown=True):
+ for entry in files:
+ # BUILD is a special file that needs to be preserved.
+ if entry == "BUILD":
+ continue
+ os.remove(os.path.join(root, entry))
+ for entry in dirs:
+ shutil.rmtree(os.path.join(root, entry))
src_dir = os.path.normpath(os.path.join(original_dir, src_rel_dir))
src_dir_len = len(src_dir) + 1
diff --git a/libc/kernel/uapi/BUILD b/libc/kernel/uapi/BUILD
new file mode 100644
index 0000000..3c9bb69
--- /dev/null
+++ b/libc/kernel/uapi/BUILD
@@ -0,0 +1,67 @@
+# Copyright (C) 2022 The Android Open Source Project
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+load("//build/bazel/rules/apis:cc_api_contribution.bzl", "cc_api_headers")
+
+package(default_visibility = ["//bionic/libc:__pkg__"])
+
+cc_api_headers(
+ name = "libc_kernel_uapi_headers",
+ hdrs = glob(["**/*.h"]),
+ system = True,
+)
+
+cc_api_headers(
+ name = "libc_kernel_uapi_asm_arm_headers",
+ hdrs = glob(["asm-arm/**/*.h"]),
+ arch = "arm",
+ include_dir = "asm-arm",
+ system = True,
+)
+
+cc_api_headers(
+ name = "libc_kernel_uapi_asm_arm64_headers",
+ hdrs = glob(["asm-arm64/**/*.h"]),
+ arch = "arm64",
+ include_dir = "asm-arm64",
+ system = True,
+)
+
+cc_api_headers(
+ name = "libc_kernel_uapi_asm_x86_headers",
+ hdrs = glob(["asm-x86/**/*.h"]),
+ arch = "x86",
+ include_dir = "asm-x86",
+ system = True,
+)
+
+cc_api_headers(
+ name = "libc_kernel_uapi_asm_x86_64_headers",
+ hdrs = glob(["asm-x86_64/**/*.h"]),
+ arch = "x86_64",
+ include_dir = "asm-x86_64",
+ system = True,
+)
diff --git a/libc/kernel/uapi/asm-arm/asm/signal.h b/libc/kernel/uapi/asm-arm/asm/signal.h
index 5f7e0c5..0424380 100644
--- a/libc/kernel/uapi/asm-arm/asm/signal.h
+++ b/libc/kernel/uapi/asm-arm/asm/signal.h
@@ -78,6 +78,6 @@
typedef struct sigaltstack {
void __user * ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 4316724..442600d 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -72,4 +72,15 @@
#define HWCAP2_ECV (1 << 19)
#define HWCAP2_AFP (1 << 20)
#define HWCAP2_RPRES (1 << 21)
+#define HWCAP2_MTE3 (1 << 22)
+#define HWCAP2_SME (1 << 23)
+#define HWCAP2_SME_I16I64 (1 << 24)
+#define HWCAP2_SME_F64F64 (1 << 25)
+#define HWCAP2_SME_I8I32 (1 << 26)
+#define HWCAP2_SME_F16F32 (1 << 27)
+#define HWCAP2_SME_B16F32 (1 << 28)
+#define HWCAP2_SME_F32F32 (1 << 29)
+#define HWCAP2_SME_FA64 (1 << 30)
+#define HWCAP2_WFXT (1UL << 31)
+#define HWCAP2_EBF16 (1UL << 32)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index c53ee87..4f9b347 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -51,9 +51,9 @@
#define KVM_ARM_TARGET_GENERIC_V8 5
#define KVM_ARM_NUM_TARGETS 6
#define KVM_ARM_DEVICE_TYPE_SHIFT 0
-#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_TYPE_MASK GENMASK(KVM_ARM_DEVICE_TYPE_SHIFT + 15, KVM_ARM_DEVICE_TYPE_SHIFT)
#define KVM_ARM_DEVICE_ID_SHIFT 16
-#define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT)
+#define KVM_ARM_DEVICE_ID_MASK GENMASK(KVM_ARM_DEVICE_ID_SHIFT + 15, KVM_ARM_DEVICE_ID_SHIFT)
#define KVM_ARM_DEVICE_VGIC_V2 0
#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
#define KVM_VGIC_V2_ADDR_TYPE_CPU 1
@@ -88,8 +88,10 @@
__u64 dbg_wcr[KVM_ARM_MAX_DBG_REGS];
__u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
};
+#define KVM_DEBUG_ARCH_HSR_HIGH_VALID (1 << 0)
struct kvm_debug_exit_arch {
__u32 hsr;
+ __u32 hsr_high;
__u64 far;
};
#define KVM_GUESTDBG_USE_SW_BP (1 << 16)
@@ -185,6 +187,21 @@
#define KVM_ARM64_SVE_VQ_MAX __SVE_VQ_MAX
#define KVM_REG_ARM64_SVE_VLS (KVM_REG_ARM64 | KVM_REG_ARM64_SVE | KVM_REG_SIZE_U512 | 0xffff)
#define KVM_ARM64_SVE_VLS_WORDS ((KVM_ARM64_SVE_VQ_MAX - KVM_ARM64_SVE_VQ_MIN) / 64 + 1)
+#define KVM_REG_ARM_FW_FEAT_BMAP (0x0016 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_FW_FEAT_BMAP_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_FW_FEAT_BMAP | ((r) & 0xffff))
+#define KVM_REG_ARM_STD_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(0)
+enum {
+ KVM_REG_ARM_STD_BIT_TRNG_V1_0 = 0,
+};
+#define KVM_REG_ARM_STD_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(1)
+enum {
+ KVM_REG_ARM_STD_HYP_BIT_PV_TIME = 0,
+};
+#define KVM_REG_ARM_VENDOR_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(2)
+enum {
+ KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0,
+ KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1,
+};
#define KVM_DEV_ARM_VGIC_GRP_ADDR 0
#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
@@ -214,6 +231,7 @@
#define KVM_ARM_VCPU_PMU_V3_IRQ 0
#define KVM_ARM_VCPU_PMU_V3_INIT 1
#define KVM_ARM_VCPU_PMU_V3_FILTER 2
+#define KVM_ARM_VCPU_PMU_V3_SET_PMU 3
#define KVM_ARM_VCPU_TIMER_CTRL 1
#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0
#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
@@ -244,5 +262,7 @@
#define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
+#define KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (1ULL << 0)
+#define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0)
#endif
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/ptrace.h b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
index 480efcf..9540c3e 100644
--- a/libc/kernel/uapi/asm-arm64/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
@@ -111,7 +111,7 @@
#define SVE_PT_SVE_FPSR_OFFSET(vq) ((SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq) + (__SVE_VQ_BYTES - 1)) / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
#define SVE_PT_SVE_FPCR_OFFSET(vq) (SVE_PT_SVE_FPSR_OFFSET(vq) + SVE_PT_SVE_FPSR_SIZE)
#define SVE_PT_SVE_SIZE(vq,flags) ((SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE - SVE_PT_SVE_OFFSET + (__SVE_VQ_BYTES - 1)) / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
-#define SVE_PT_SIZE(vq,flags) (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ? SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags) : SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags))
+#define SVE_PT_SIZE(vq,flags) (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ? SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags) : ((((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD ? SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags) : SVE_PT_REGS_OFFSET)))
struct user_pac_mask {
__u64 data_mask;
__u64 insn_mask;
@@ -125,5 +125,19 @@
struct user_pac_generic_keys {
__uint128_t apgakey;
};
+struct user_za_header {
+ __u32 size;
+ __u32 max_size;
+ __u16 vl;
+ __u16 max_vl;
+ __u16 flags;
+ __u16 __reserved;
+};
+#define ZA_PT_VL_INHERIT ((1 << 17) >> 16)
+#define ZA_PT_VL_ONEXEC ((1 << 18) >> 16)
+#define ZA_PT_ZA_OFFSET ((sizeof(struct user_za_header) + (__SVE_VQ_BYTES - 1)) / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
+#define ZA_PT_ZAV_OFFSET(vq,n) (ZA_PT_ZA_OFFSET + ((vq * __SVE_VQ_BYTES) * n))
+#define ZA_PT_ZA_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+#define ZA_PT_SIZE(vq) (ZA_PT_ZA_OFFSET + ZA_PT_ZA_SIZE(vq))
#endif
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index 518079d..04aa593 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -55,6 +55,14 @@
struct sve_context {
struct _aarch64_ctx head;
__u16 vl;
+ __u16 flags;
+ __u16 __reserved[2];
+};
+#define SVE_SIG_FLAG_SM 0x1
+#define ZA_MAGIC 0x54366345
+struct za_context {
+ struct _aarch64_ctx head;
+ __u16 vl;
__u16 __reserved[3];
};
#endif
@@ -82,4 +90,8 @@
#define SVE_SIG_FFR_OFFSET(vq) (SVE_SIG_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
#define SVE_SIG_REGS_SIZE(vq) (__SVE_FFR_OFFSET(vq) + __SVE_FFR_SIZE(vq))
#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
+#define ZA_SIG_REGS_OFFSET ((sizeof(struct za_context) + (__SVE_VQ_BYTES - 1)) / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
+#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+#define ZA_SIG_ZAV_OFFSET(vq,n) (ZA_SIG_REGS_OFFSET + (SVE_SIG_ZREG_SIZE(vq) * n))
+#define ZA_SIG_CONTEXT_SIZE(vq) (ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
#endif
diff --git a/libc/kernel/uapi/asm-generic/fcntl.h b/libc/kernel/uapi/asm-generic/fcntl.h
index a2cb5f4..ea8c108 100644
--- a/libc/kernel/uapi/asm-generic/fcntl.h
+++ b/libc/kernel/uapi/asm-generic/fcntl.h
@@ -100,7 +100,7 @@
#define F_SETSIG 10
#define F_GETSIG 11
#endif
-#ifndef __LP64__
+#if __BITS_PER_LONG == 32
#ifndef F_GETLK64
#define F_GETLK64 12
#define F_SETLK64 13
@@ -144,13 +144,5 @@
#define LOCK_RW 192
#define F_LINUX_SPECIFIC_BASE 1024
#ifndef HAVE_ARCH_STRUCT_FLOCK
-#ifndef __ARCH_FLOCK_PAD
-#define __ARCH_FLOCK_PAD
-#endif
-#endif
-#ifndef HAVE_ARCH_STRUCT_FLOCK64
-#ifndef __ARCH_FLOCK64_PAD
-#define __ARCH_FLOCK64_PAD
-#endif
#endif
#endif
diff --git a/libc/kernel/uapi/asm-generic/mman-common.h b/libc/kernel/uapi/asm-generic/mman-common.h
index 9440576..e96f4cc 100644
--- a/libc/kernel/uapi/asm-generic/mman-common.h
+++ b/libc/kernel/uapi/asm-generic/mman-common.h
@@ -62,6 +62,7 @@
#define MADV_PAGEOUT 21
#define MADV_POPULATE_READ 22
#define MADV_POPULATE_WRITE 23
+#define MADV_DONTNEED_LOCKED 24
#define MAP_FILE 0
#define PKEY_DISABLE_ACCESS 0x1
#define PKEY_DISABLE_WRITE 0x2
diff --git a/libc/kernel/uapi/asm-generic/shmbuf.h b/libc/kernel/uapi/asm-generic/shmbuf.h
index 067ffbc..11487f4 100644
--- a/libc/kernel/uapi/asm-generic/shmbuf.h
+++ b/libc/kernel/uapi/asm-generic/shmbuf.h
@@ -19,9 +19,11 @@
#ifndef __ASM_GENERIC_SHMBUF_H
#define __ASM_GENERIC_SHMBUF_H
#include <asm/bitsperlong.h>
+#include <asm/ipcbuf.h>
+#include <asm/posix_types.h>
struct shmid64_ds {
struct ipc64_perm shm_perm;
- size_t shm_segsz;
+ __kernel_size_t shm_segsz;
#if __BITS_PER_LONG == 64
long shm_atime;
long shm_dtime;
diff --git a/libc/kernel/uapi/asm-generic/siginfo.h b/libc/kernel/uapi/asm-generic/siginfo.h
index f9199e5..c5e4178 100644
--- a/libc/kernel/uapi/asm-generic/siginfo.h
+++ b/libc/kernel/uapi/asm-generic/siginfo.h
@@ -80,6 +80,7 @@
struct {
unsigned long _data;
__u32 _type;
+ __u32 _flags;
} _perf;
};
} _sigfault;
@@ -125,6 +126,7 @@
#define si_pkey _sifields._sigfault._addr_pkey._pkey
#define si_perf_data _sifields._sigfault._perf._data
#define si_perf_type _sifields._sigfault._perf._type
+#define si_perf_flags _sifields._sigfault._perf._flags
#define si_band _sifields._sigpoll._band
#define si_fd _sifields._sigpoll._fd
#define si_call_addr _sifields._sigsys._call_addr
@@ -197,6 +199,7 @@
#define TRAP_UNK 5
#define TRAP_PERF 6
#define NSIGTRAP 6
+#define TRAP_PERF_FLAG_ASYNC (1u << 0)
#define CLD_EXITED 1
#define CLD_KILLED 2
#define CLD_DUMPED 3
diff --git a/libc/kernel/uapi/asm-generic/signal.h b/libc/kernel/uapi/asm-generic/signal.h
index 874fece..5cb1dce 100644
--- a/libc/kernel/uapi/asm-generic/signal.h
+++ b/libc/kernel/uapi/asm-generic/signal.h
@@ -84,7 +84,7 @@
typedef struct sigaltstack {
void __user * ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
#endif
#endif
diff --git a/libc/kernel/uapi/asm-generic/socket.h b/libc/kernel/uapi/asm-generic/socket.h
index 6767993..1a321bf 100644
--- a/libc/kernel/uapi/asm-generic/socket.h
+++ b/libc/kernel/uapi/asm-generic/socket.h
@@ -100,6 +100,8 @@
#define SO_NETNS_COOKIE 71
#define SO_BUF_LOCK 72
#define SO_RESERVE_MEM 73
+#define SO_TXREHASH 74
+#define SO_RCVMARK 75
#if __BITS_PER_LONG == 64 || defined(__x86_64__) && defined(__ILP32__)
#define SO_TIMESTAMP SO_TIMESTAMP_OLD
#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
diff --git a/libc/kernel/uapi/asm-generic/termbits-common.h b/libc/kernel/uapi/asm-generic/termbits-common.h
new file mode 100644
index 0000000..281eee8
--- /dev/null
+++ b/libc/kernel/uapi/asm-generic/termbits-common.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 __ASM_GENERIC_TERMBITS_COMMON_H
+#define __ASM_GENERIC_TERMBITS_COMMON_H
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+#define IGNBRK 0x001
+#define BRKINT 0x002
+#define IGNPAR 0x004
+#define PARMRK 0x008
+#define INPCK 0x010
+#define ISTRIP 0x020
+#define INLCR 0x040
+#define IGNCR 0x080
+#define ICRNL 0x100
+#define IXANY 0x800
+#define OPOST 0x01
+#define OCRNL 0x08
+#define ONOCR 0x10
+#define ONLRET 0x20
+#define OFILL 0x40
+#define OFDEL 0x80
+#define B0 0x00000000
+#define B50 0x00000001
+#define B75 0x00000002
+#define B110 0x00000003
+#define B134 0x00000004
+#define B150 0x00000005
+#define B200 0x00000006
+#define B300 0x00000007
+#define B600 0x00000008
+#define B1200 0x00000009
+#define B1800 0x0000000a
+#define B2400 0x0000000b
+#define B4800 0x0000000c
+#define B9600 0x0000000d
+#define B19200 0x0000000e
+#define B38400 0x0000000f
+#define EXTA B19200
+#define EXTB B38400
+#define ADDRB 0x20000000
+#define CMSPAR 0x40000000
+#define CRTSCTS 0x80000000
+#define IBSHIFT 16
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+#endif
diff --git a/libc/kernel/uapi/asm-generic/termbits.h b/libc/kernel/uapi/asm-generic/termbits.h
index b592964..87d6c82 100644
--- a/libc/kernel/uapi/asm-generic/termbits.h
+++ b/libc/kernel/uapi/asm-generic/termbits.h
@@ -18,9 +18,7 @@
****************************************************************************/
#ifndef __ASM_GENERIC_TERMBITS_H
#define __ASM_GENERIC_TERMBITS_H
-#include <linux/posix_types.h>
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
+#include <asm-generic/termbits-common.h>
typedef unsigned int tcflag_t;
#define NCCS 19
struct termios {
@@ -68,126 +66,82 @@
#define VWERASE 14
#define VLNEXT 15
#define VEOL2 16
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK 0000020
-#define ISTRIP 0000040
-#define INLCR 0000100
-#define IGNCR 0000200
-#define ICRNL 0000400
-#define IUCLC 0001000
-#define IXON 0002000
-#define IXANY 0004000
-#define IXOFF 0010000
-#define IMAXBEL 0020000
-#define IUTF8 0040000
-#define OPOST 0000001
-#define OLCUC 0000002
-#define ONLCR 0000004
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-#define OFILL 0000100
-#define OFDEL 0000200
-#define NLDLY 0000400
-#define NL0 0000000
-#define NL1 0000400
-#define CRDLY 0003000
-#define CR0 0000000
-#define CR1 0001000
-#define CR2 0002000
-#define CR3 0003000
-#define TABDLY 0014000
-#define TAB0 0000000
-#define TAB1 0004000
-#define TAB2 0010000
-#define TAB3 0014000
-#define XTABS 0014000
-#define BSDLY 0020000
-#define BS0 0000000
-#define BS1 0020000
-#define VTDLY 0040000
-#define VT0 0000000
-#define VT1 0040000
-#define FFDLY 0100000
-#define FF0 0000000
-#define FF1 0100000
-#define CBAUD 0010017
-#define B0 0000000
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE 0000060
-#define CS5 0000000
-#define CS6 0000020
-#define CS7 0000040
-#define CS8 0000060
-#define CSTOPB 0000100
-#define CREAD 0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL 0002000
-#define CLOCAL 0004000
-#define CBAUDEX 0010000
-#define BOTHER 0010000
-#define B57600 0010001
-#define B115200 0010002
-#define B230400 0010003
-#define B460800 0010004
-#define B500000 0010005
-#define B576000 0010006
-#define B921600 0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-#define CIBAUD 002003600000
-#define CMSPAR 010000000000
-#define CRTSCTS 020000000000
-#define IBSHIFT 16
-#define ISIG 0000001
-#define ICANON 0000002
-#define XCASE 0000004
-#define ECHO 0000010
-#define ECHOE 0000020
-#define ECHOK 0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-#define IEXTEN 0100000
-#define EXTPROC 0200000
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
+#define IUCLC 0x0200
+#define IXON 0x0400
+#define IXOFF 0x1000
+#define IMAXBEL 0x2000
+#define IUTF8 0x4000
+#define OLCUC 0x00002
+#define ONLCR 0x00004
+#define NLDLY 0x00100
+#define NL0 0x00000
+#define NL1 0x00100
+#define CRDLY 0x00600
+#define CR0 0x00000
+#define CR1 0x00200
+#define CR2 0x00400
+#define CR3 0x00600
+#define TABDLY 0x01800
+#define TAB0 0x00000
+#define TAB1 0x00800
+#define TAB2 0x01000
+#define TAB3 0x01800
+#define XTABS 0x01800
+#define BSDLY 0x02000
+#define BS0 0x00000
+#define BS1 0x02000
+#define VTDLY 0x04000
+#define VT0 0x00000
+#define VT1 0x04000
+#define FFDLY 0x08000
+#define FF0 0x00000
+#define FF1 0x08000
+#define CBAUD 0x0000100f
+#define CSIZE 0x00000030
+#define CS5 0x00000000
+#define CS6 0x00000010
+#define CS7 0x00000020
+#define CS8 0x00000030
+#define CSTOPB 0x00000040
+#define CREAD 0x00000080
+#define PARENB 0x00000100
+#define PARODD 0x00000200
+#define HUPCL 0x00000400
+#define CLOCAL 0x00000800
+#define CBAUDEX 0x00001000
+#define BOTHER 0x00001000
+#define B57600 0x00001001
+#define B115200 0x00001002
+#define B230400 0x00001003
+#define B460800 0x00001004
+#define B500000 0x00001005
+#define B576000 0x00001006
+#define B921600 0x00001007
+#define B1000000 0x00001008
+#define B1152000 0x00001009
+#define B1500000 0x0000100a
+#define B2000000 0x0000100b
+#define B2500000 0x0000100c
+#define B3000000 0x0000100d
+#define B3500000 0x0000100e
+#define B4000000 0x0000100f
+#define CIBAUD 0x100f0000
+#define ISIG 0x00001
+#define ICANON 0x00002
+#define XCASE 0x00004
+#define ECHO 0x00008
+#define ECHOE 0x00010
+#define ECHOK 0x00020
+#define ECHONL 0x00040
+#define NOFLSH 0x00080
+#define TOSTOP 0x00100
+#define ECHOCTL 0x00200
+#define ECHOPRT 0x00400
+#define ECHOKE 0x00800
+#define FLUSHO 0x01000
+#define PENDIN 0x04000
+#define IEXTEN 0x08000
+#define EXTPROC 0x10000
#define TCSANOW 0
#define TCSADRAIN 1
#define TCSAFLUSH 2
diff --git a/libc/kernel/uapi/asm-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index 4b9f174..d23958b 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -360,7 +360,7 @@
#endif
#define __NR_rseq 293
#define __NR_kexec_file_load 294
-#if __BITS_PER_LONG == 32
+#if defined(__SYSCALL_COMPAT) || __BITS_PER_LONG == 32
#define __NR_clock_gettime64 403
#define __NR_clock_settime64 404
#define __NR_clock_adjtime64 405
diff --git a/libc/kernel/uapi/asm-riscv/asm/auxvec.h b/libc/kernel/uapi/asm-riscv/asm/auxvec.h
new file mode 100644
index 0000000..b0e22af
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/auxvec.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_RISCV_AUXVEC_H
+#define _UAPI_ASM_RISCV_AUXVEC_H
+#define AT_SYSINFO_EHDR 33
+#define AT_L1I_CACHESIZE 40
+#define AT_L1I_CACHEGEOMETRY 41
+#define AT_L1D_CACHESIZE 42
+#define AT_L1D_CACHEGEOMETRY 43
+#define AT_L2_CACHESIZE 44
+#define AT_L2_CACHEGEOMETRY 45
+#define AT_VECTOR_SIZE_ARCH 7
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/bitsperlong.h b/libc/kernel/uapi/asm-riscv/asm/bitsperlong.h
new file mode 100644
index 0000000..098b610
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/bitsperlong.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_RISCV_BITSPERLONG_H
+#define _UAPI_ASM_RISCV_BITSPERLONG_H
+#define __BITS_PER_LONG (__SIZEOF_POINTER__ * 8)
+#include <asm-generic/bitsperlong.h>
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/bpf_perf_event.h b/libc/kernel/uapi/asm-riscv/asm/bpf_perf_event.h
new file mode 100644
index 0000000..47c09fd
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/bpf_perf_event.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
+#define _UAPI__ASM_BPF_PERF_EVENT_H__
+#include <asm/ptrace.h>
+typedef struct user_regs_struct bpf_user_pt_regs_t;
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/byteorder.h b/libc/kernel/uapi/asm-riscv/asm/byteorder.h
new file mode 100644
index 0000000..42afc14
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/byteorder.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_RISCV_BYTEORDER_H
+#define _UAPI_ASM_RISCV_BYTEORDER_H
+#include <linux/byteorder/little_endian.h>
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/elf.h b/libc/kernel/uapi/asm-riscv/asm/elf.h
new file mode 100644
index 0000000..07593d9
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/elf.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_RISCV_ELF_H
+#define _UAPI_ASM_RISCV_ELF_H
+#include <asm/ptrace.h>
+typedef unsigned long elf_greg_t;
+typedef struct user_regs_struct elf_gregset_t;
+#define ELF_NGREG (sizeof(elf_gregset_t) / sizeof(elf_greg_t))
+typedef __u64 elf_fpreg_t;
+typedef union __riscv_fp_state elf_fpregset_t;
+#define ELF_NFPREG (sizeof(struct __riscv_d_ext_state) / sizeof(elf_fpreg_t))
+#if __riscv_xlen == 64
+#define ELF_RISCV_R_SYM(r_info) ELF64_R_SYM(r_info)
+#define ELF_RISCV_R_TYPE(r_info) ELF64_R_TYPE(r_info)
+#else
+#define ELF_RISCV_R_SYM(r_info) ELF32_R_SYM(r_info)
+#define ELF_RISCV_R_TYPE(r_info) ELF32_R_TYPE(r_info)
+#endif
+#define R_RISCV_NONE 0
+#define R_RISCV_32 1
+#define R_RISCV_64 2
+#define R_RISCV_RELATIVE 3
+#define R_RISCV_COPY 4
+#define R_RISCV_JUMP_SLOT 5
+#define R_RISCV_TLS_DTPMOD32 6
+#define R_RISCV_TLS_DTPMOD64 7
+#define R_RISCV_TLS_DTPREL32 8
+#define R_RISCV_TLS_DTPREL64 9
+#define R_RISCV_TLS_TPREL32 10
+#define R_RISCV_TLS_TPREL64 11
+#define R_RISCV_BRANCH 16
+#define R_RISCV_JAL 17
+#define R_RISCV_CALL 18
+#define R_RISCV_CALL_PLT 19
+#define R_RISCV_GOT_HI20 20
+#define R_RISCV_TLS_GOT_HI20 21
+#define R_RISCV_TLS_GD_HI20 22
+#define R_RISCV_PCREL_HI20 23
+#define R_RISCV_PCREL_LO12_I 24
+#define R_RISCV_PCREL_LO12_S 25
+#define R_RISCV_HI20 26
+#define R_RISCV_LO12_I 27
+#define R_RISCV_LO12_S 28
+#define R_RISCV_TPREL_HI20 29
+#define R_RISCV_TPREL_LO12_I 30
+#define R_RISCV_TPREL_LO12_S 31
+#define R_RISCV_TPREL_ADD 32
+#define R_RISCV_ADD8 33
+#define R_RISCV_ADD16 34
+#define R_RISCV_ADD32 35
+#define R_RISCV_ADD64 36
+#define R_RISCV_SUB8 37
+#define R_RISCV_SUB16 38
+#define R_RISCV_SUB32 39
+#define R_RISCV_SUB64 40
+#define R_RISCV_GNU_VTINHERIT 41
+#define R_RISCV_GNU_VTENTRY 42
+#define R_RISCV_ALIGN 43
+#define R_RISCV_RVC_BRANCH 44
+#define R_RISCV_RVC_JUMP 45
+#define R_RISCV_LUI 46
+#define R_RISCV_GPREL_I 47
+#define R_RISCV_GPREL_S 48
+#define R_RISCV_TPREL_I 49
+#define R_RISCV_TPREL_S 50
+#define R_RISCV_RELAX 51
+#define R_RISCV_SUB6 52
+#define R_RISCV_SET6 53
+#define R_RISCV_SET8 54
+#define R_RISCV_SET16 55
+#define R_RISCV_SET32 56
+#define R_RISCV_32_PCREL 57
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/errno.h b/libc/kernel/uapi/asm-riscv/asm/errno.h
new file mode 100644
index 0000000..392cd94
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/errno.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/errno.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/fcntl.h b/libc/kernel/uapi/asm-riscv/asm/fcntl.h
new file mode 100644
index 0000000..518d3a7
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/fcntl.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/fcntl.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/hwcap.h b/libc/kernel/uapi/asm-riscv/asm/hwcap.h
new file mode 100644
index 0000000..d130cf7
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/hwcap.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_RISCV_HWCAP_H
+#define _UAPI_ASM_RISCV_HWCAP_H
+#define COMPAT_HWCAP_ISA_I (1 << ('I' - 'A'))
+#define COMPAT_HWCAP_ISA_M (1 << ('M' - 'A'))
+#define COMPAT_HWCAP_ISA_A (1 << ('A' - 'A'))
+#define COMPAT_HWCAP_ISA_F (1 << ('F' - 'A'))
+#define COMPAT_HWCAP_ISA_D (1 << ('D' - 'A'))
+#define COMPAT_HWCAP_ISA_C (1 << ('C' - 'A'))
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/ioctl.h b/libc/kernel/uapi/asm-riscv/asm/ioctl.h
new file mode 100644
index 0000000..7b7bd37
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/ioctl.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/ioctl.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/ioctls.h b/libc/kernel/uapi/asm-riscv/asm/ioctls.h
new file mode 100644
index 0000000..0c66935
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/ioctls.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/ioctls.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/ipcbuf.h b/libc/kernel/uapi/asm-riscv/asm/ipcbuf.h
new file mode 100644
index 0000000..0021f14
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/ipcbuf.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/ipcbuf.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/kvm.h b/libc/kernel/uapi/asm-riscv/asm/kvm.h
new file mode 100644
index 0000000..8a317b6
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/kvm.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_KVM_RISCV_H
+#define __LINUX_KVM_RISCV_H
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#include <asm/ptrace.h>
+#define __KVM_HAVE_READONLY_MEM
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
+#define KVM_INTERRUPT_SET - 1U
+#define KVM_INTERRUPT_UNSET - 2U
+struct kvm_regs {
+};
+struct kvm_fpu {
+};
+struct kvm_debug_exit_arch {
+};
+struct kvm_guest_debug_arch {
+};
+struct kvm_sync_regs {
+};
+struct kvm_sregs {
+};
+struct kvm_riscv_config {
+ unsigned long isa;
+};
+struct kvm_riscv_core {
+ struct user_regs_struct regs;
+ unsigned long mode;
+};
+#define KVM_RISCV_MODE_S 1
+#define KVM_RISCV_MODE_U 0
+struct kvm_riscv_csr {
+ unsigned long sstatus;
+ unsigned long sie;
+ unsigned long stvec;
+ unsigned long sscratch;
+ unsigned long sepc;
+ unsigned long scause;
+ unsigned long stval;
+ unsigned long sip;
+ unsigned long satp;
+ unsigned long scounteren;
+};
+struct kvm_riscv_timer {
+ __u64 frequency;
+ __u64 time;
+ __u64 compare;
+ __u64 state;
+};
+enum KVM_RISCV_ISA_EXT_ID {
+ KVM_RISCV_ISA_EXT_A = 0,
+ KVM_RISCV_ISA_EXT_C,
+ KVM_RISCV_ISA_EXT_D,
+ KVM_RISCV_ISA_EXT_F,
+ KVM_RISCV_ISA_EXT_H,
+ KVM_RISCV_ISA_EXT_I,
+ KVM_RISCV_ISA_EXT_M,
+ KVM_RISCV_ISA_EXT_SVPBMT,
+ KVM_RISCV_ISA_EXT_SSTC,
+ KVM_RISCV_ISA_EXT_MAX,
+};
+#define KVM_RISCV_TIMER_STATE_OFF 0
+#define KVM_RISCV_TIMER_STATE_ON 1
+#define KVM_REG_SIZE(id) (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+#define KVM_REG_RISCV_TYPE_MASK 0x00000000FF000000
+#define KVM_REG_RISCV_TYPE_SHIFT 24
+#define KVM_REG_RISCV_CONFIG (0x01 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_CONFIG_REG(name) (offsetof(struct kvm_riscv_config, name) / sizeof(unsigned long))
+#define KVM_REG_RISCV_CORE (0x02 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_CORE_REG(name) (offsetof(struct kvm_riscv_core, name) / sizeof(unsigned long))
+#define KVM_REG_RISCV_CSR (0x03 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_CSR_REG(name) (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long))
+#define KVM_REG_RISCV_TIMER (0x04 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_TIMER_REG(name) (offsetof(struct kvm_riscv_timer, name) / sizeof(__u64))
+#define KVM_REG_RISCV_FP_F (0x05 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_FP_F_REG(name) (offsetof(struct __riscv_f_ext_state, name) / sizeof(__u32))
+#define KVM_REG_RISCV_FP_D (0x06 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_FP_D_REG(name) (offsetof(struct __riscv_d_ext_state, name) / sizeof(__u64))
+#define KVM_REG_RISCV_ISA_EXT (0x07 << KVM_REG_RISCV_TYPE_SHIFT)
+#endif
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/mman.h b/libc/kernel/uapi/asm-riscv/asm/mman.h
new file mode 100644
index 0000000..6c23fb6
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/mman.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/mman.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/msgbuf.h b/libc/kernel/uapi/asm-riscv/asm/msgbuf.h
new file mode 100644
index 0000000..7809e3c
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/msgbuf.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/msgbuf.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/param.h b/libc/kernel/uapi/asm-riscv/asm/param.h
new file mode 100644
index 0000000..5ccf935
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/param.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/param.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/perf_regs.h b/libc/kernel/uapi/asm-riscv/asm/perf_regs.h
new file mode 100644
index 0000000..ceb0bbe
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/perf_regs.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 _ASM_RISCV_PERF_REGS_H
+#define _ASM_RISCV_PERF_REGS_H
+enum perf_event_riscv_regs {
+ PERF_REG_RISCV_PC,
+ PERF_REG_RISCV_RA,
+ PERF_REG_RISCV_SP,
+ PERF_REG_RISCV_GP,
+ PERF_REG_RISCV_TP,
+ PERF_REG_RISCV_T0,
+ PERF_REG_RISCV_T1,
+ PERF_REG_RISCV_T2,
+ PERF_REG_RISCV_S0,
+ PERF_REG_RISCV_S1,
+ PERF_REG_RISCV_A0,
+ PERF_REG_RISCV_A1,
+ PERF_REG_RISCV_A2,
+ PERF_REG_RISCV_A3,
+ PERF_REG_RISCV_A4,
+ PERF_REG_RISCV_A5,
+ PERF_REG_RISCV_A6,
+ PERF_REG_RISCV_A7,
+ PERF_REG_RISCV_S2,
+ PERF_REG_RISCV_S3,
+ PERF_REG_RISCV_S4,
+ PERF_REG_RISCV_S5,
+ PERF_REG_RISCV_S6,
+ PERF_REG_RISCV_S7,
+ PERF_REG_RISCV_S8,
+ PERF_REG_RISCV_S9,
+ PERF_REG_RISCV_S10,
+ PERF_REG_RISCV_S11,
+ PERF_REG_RISCV_T3,
+ PERF_REG_RISCV_T4,
+ PERF_REG_RISCV_T5,
+ PERF_REG_RISCV_T6,
+ PERF_REG_RISCV_MAX,
+};
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/poll.h b/libc/kernel/uapi/asm-riscv/asm/poll.h
new file mode 100644
index 0000000..d7e8adc
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/poll.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/poll.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/posix_types.h b/libc/kernel/uapi/asm-riscv/asm/posix_types.h
new file mode 100644
index 0000000..1b89253
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/posix_types.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/posix_types.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/ptrace.h b/libc/kernel/uapi/asm-riscv/asm/ptrace.h
new file mode 100644
index 0000000..94e4ac9
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/ptrace.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_RISCV_PTRACE_H
+#define _UAPI_ASM_RISCV_PTRACE_H
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+struct user_regs_struct {
+ unsigned long pc;
+ unsigned long ra;
+ unsigned long sp;
+ unsigned long gp;
+ unsigned long tp;
+ unsigned long t0;
+ unsigned long t1;
+ unsigned long t2;
+ unsigned long s0;
+ unsigned long s1;
+ unsigned long a0;
+ unsigned long a1;
+ unsigned long a2;
+ unsigned long a3;
+ unsigned long a4;
+ unsigned long a5;
+ unsigned long a6;
+ unsigned long a7;
+ unsigned long s2;
+ unsigned long s3;
+ unsigned long s4;
+ unsigned long s5;
+ unsigned long s6;
+ unsigned long s7;
+ unsigned long s8;
+ unsigned long s9;
+ unsigned long s10;
+ unsigned long s11;
+ unsigned long t3;
+ unsigned long t4;
+ unsigned long t5;
+ unsigned long t6;
+};
+struct __riscv_f_ext_state {
+ __u32 f[32];
+ __u32 fcsr;
+};
+struct __riscv_d_ext_state {
+ __u64 f[32];
+ __u32 fcsr;
+};
+struct __riscv_q_ext_state {
+ __u64 f[64] __attribute__((aligned(16)));
+ __u32 fcsr;
+ __u32 reserved[3];
+};
+union __riscv_fp_state {
+ struct __riscv_f_ext_state f;
+ struct __riscv_d_ext_state d;
+ struct __riscv_q_ext_state q;
+};
+#endif
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/resource.h b/libc/kernel/uapi/asm-riscv/asm/resource.h
new file mode 100644
index 0000000..371adb5
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/resource.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/resource.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/sembuf.h b/libc/kernel/uapi/asm-riscv/asm/sembuf.h
new file mode 100644
index 0000000..6ce6549
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/sembuf.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/sembuf.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/setup.h b/libc/kernel/uapi/asm-riscv/asm/setup.h
new file mode 100644
index 0000000..940c4db
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/setup.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/setup.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/shmbuf.h b/libc/kernel/uapi/asm-riscv/asm/shmbuf.h
new file mode 100644
index 0000000..fe8b1be
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/shmbuf.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/shmbuf.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/sigcontext.h b/libc/kernel/uapi/asm-riscv/asm/sigcontext.h
new file mode 100644
index 0000000..0553b94
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/sigcontext.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_RISCV_SIGCONTEXT_H
+#define _UAPI_ASM_RISCV_SIGCONTEXT_H
+#include <asm/ptrace.h>
+struct sigcontext {
+ struct user_regs_struct sc_regs;
+ union __riscv_fp_state sc_fpregs;
+};
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/siginfo.h b/libc/kernel/uapi/asm-riscv/asm/siginfo.h
new file mode 100644
index 0000000..a31ebb2
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/siginfo.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/siginfo.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/signal.h b/libc/kernel/uapi/asm-riscv/asm/signal.h
new file mode 100644
index 0000000..64373fe
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/signal.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/signal.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/socket.h b/libc/kernel/uapi/asm-riscv/asm/socket.h
new file mode 100644
index 0000000..50a9874
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/socket.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/socket.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/sockios.h b/libc/kernel/uapi/asm-riscv/asm/sockios.h
new file mode 100644
index 0000000..710db92
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/sockios.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/sockios.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/stat.h b/libc/kernel/uapi/asm-riscv/asm/stat.h
new file mode 100644
index 0000000..af7ebfc
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/stat.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/stat.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/statfs.h b/libc/kernel/uapi/asm-riscv/asm/statfs.h
new file mode 100644
index 0000000..93de275
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/statfs.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/statfs.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/swab.h b/libc/kernel/uapi/asm-riscv/asm/swab.h
new file mode 100644
index 0000000..0049f53
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/swab.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/swab.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/termbits.h b/libc/kernel/uapi/asm-riscv/asm/termbits.h
new file mode 100644
index 0000000..42af6fe
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/termbits.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/termbits.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/termios.h b/libc/kernel/uapi/asm-riscv/asm/termios.h
new file mode 100644
index 0000000..feca4c6
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/termios.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/termios.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/types.h b/libc/kernel/uapi/asm-riscv/asm/types.h
new file mode 100644
index 0000000..8250f43
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/types.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/types.h>
diff --git a/libc/kernel/uapi/asm-riscv/asm/ucontext.h b/libc/kernel/uapi/asm-riscv/asm/ucontext.h
new file mode 100644
index 0000000..8b72cc1
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/ucontext.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_RISCV_UCONTEXT_H
+#define _UAPI_ASM_RISCV_UCONTEXT_H
+#include <linux/types.h>
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext * uc_link;
+ stack_t uc_stack;
+ sigset_t uc_sigmask;
+ __u8 __linux_unused[1024 / 8 - sizeof(sigset_t)];
+ struct sigcontext uc_mcontext;
+};
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/unistd.h b/libc/kernel/uapi/asm-riscv/asm/unistd.h
new file mode 100644
index 0000000..665b820
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/unistd.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#if defined(__LP64__) && !defined(__SYSCALL_COMPAT)
+#define __ARCH_WANT_NEW_STAT
+#define __ARCH_WANT_SET_GET_RLIMIT
+#endif
+#define __ARCH_WANT_SYS_CLONE3
+#define __ARCH_WANT_MEMFD_SECRET
+#include <asm-generic/unistd.h>
+#ifndef __NR_riscv_flush_icache
+#define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15)
+#endif
+__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache)
diff --git a/libc/kernel/uapi/asm-x86/asm/amd_hsmp.h b/libc/kernel/uapi/asm-x86/asm/amd_hsmp.h
new file mode 100644
index 0000000..c026aac
--- /dev/null
+++ b/libc/kernel/uapi/asm-x86/asm/amd_hsmp.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_X86_AMD_HSMP_H_
+#define _UAPI_ASM_X86_AMD_HSMP_H_
+#include <linux/types.h>
+#pragma pack(4)
+#define HSMP_MAX_MSG_LEN 8
+enum hsmp_message_ids {
+ HSMP_TEST = 1,
+ HSMP_GET_SMU_VER,
+ HSMP_GET_PROTO_VER,
+ HSMP_GET_SOCKET_POWER,
+ HSMP_SET_SOCKET_POWER_LIMIT,
+ HSMP_GET_SOCKET_POWER_LIMIT,
+ HSMP_GET_SOCKET_POWER_LIMIT_MAX,
+ HSMP_SET_BOOST_LIMIT,
+ HSMP_SET_BOOST_LIMIT_SOCKET,
+ HSMP_GET_BOOST_LIMIT,
+ HSMP_GET_PROC_HOT,
+ HSMP_SET_XGMI_LINK_WIDTH,
+ HSMP_SET_DF_PSTATE,
+ HSMP_SET_AUTO_DF_PSTATE,
+ HSMP_GET_FCLK_MCLK,
+ HSMP_GET_CCLK_THROTTLE_LIMIT,
+ HSMP_GET_C0_PERCENT,
+ HSMP_SET_NBIO_DPM_LEVEL,
+ HSMP_GET_NBIO_DPM_LEVEL,
+ HSMP_GET_DDR_BANDWIDTH,
+ HSMP_GET_TEMP_MONITOR,
+ HSMP_GET_DIMM_TEMP_RANGE,
+ HSMP_GET_DIMM_POWER,
+ HSMP_GET_DIMM_THERMAL,
+ HSMP_GET_SOCKET_FREQ_LIMIT,
+ HSMP_GET_CCLK_CORE_LIMIT,
+ HSMP_GET_RAILS_SVI,
+ HSMP_GET_SOCKET_FMAX_FMIN,
+ HSMP_GET_IOLINK_BANDWITH,
+ HSMP_GET_XGMI_BANDWITH,
+ HSMP_SET_GMI3_WIDTH,
+ HSMP_SET_PCI_RATE,
+ HSMP_SET_POWER_MODE,
+ HSMP_SET_PSTATE_MAX_MIN,
+ HSMP_MSG_ID_MAX,
+};
+struct hsmp_message {
+ __u32 msg_id;
+ __u16 num_args;
+ __u16 response_sz;
+ __u32 args[HSMP_MAX_MSG_LEN];
+ __u16 sock_ind;
+};
+enum hsmp_msg_type {
+ HSMP_RSVD = - 1,
+ HSMP_SET = 0,
+ HSMP_GET = 1,
+};
+struct hsmp_msg_desc {
+ int num_args;
+ int response_sz;
+ enum hsmp_msg_type type;
+};
+static const struct hsmp_msg_desc hsmp_msg_desc_table[] = {
+ {
+ 0, 0, HSMP_RSVD
+ }
+ , {
+ 1, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 1, 0, HSMP_SET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 1, 0, HSMP_SET
+ }
+ , {
+ 1, 0, HSMP_SET
+ }
+ , {
+ 1, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 1, 0, HSMP_SET
+ }
+ , {
+ 1, 0, HSMP_SET
+ }
+ , {
+ 0, 0, HSMP_SET
+ }
+ , {
+ 0, 2, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 1, 0, HSMP_SET
+ }
+ , {
+ 1, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 1, 1, HSMP_GET
+ }
+ , {
+ 1, 1, HSMP_GET
+ }
+ , {
+ 1, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 1, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 0, 1, HSMP_GET
+ }
+ , {
+ 1, 1, HSMP_GET
+ }
+ , {
+ 1, 1, HSMP_GET
+ }
+ , {
+ 1, 0, HSMP_SET
+ }
+ , {
+ 1, 1, HSMP_SET
+ }
+ , {
+ 1, 0, HSMP_SET
+ }
+ , {
+ 1, 0, HSMP_SET
+ }
+ ,
+};
+#pragma pack()
+#define HSMP_BASE_IOCTL_NR 0xF8
+#define HSMP_IOCTL_CMD _IOWR(HSMP_BASE_IOCTL_NR, 0, struct hsmp_message)
+#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/bootparam.h b/libc/kernel/uapi/asm-x86/asm/bootparam.h
index 7401135..ab9d7f3 100644
--- a/libc/kernel/uapi/asm-x86/asm/bootparam.h
+++ b/libc/kernel/uapi/asm-x86/asm/bootparam.h
@@ -25,8 +25,12 @@
#define SETUP_EFI 4
#define SETUP_APPLE_PROPERTIES 5
#define SETUP_JAILHOUSE 6
+#define SETUP_CC_BLOB 7
+#define SETUP_IMA 8
+#define SETUP_RNG_SEED 9
+#define SETUP_ENUM_MAX SETUP_RNG_SEED
#define SETUP_INDIRECT (1 << 31)
-#define SETUP_TYPE_MAX (SETUP_INDIRECT | SETUP_JAILHOUSE)
+#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT)
#define RAMDISK_IMAGE_START_MASK 0x07FF
#define RAMDISK_PROMPT_FLAG 0x8000
#define RAMDISK_LOAD_FLAG 0x4000
@@ -53,7 +57,7 @@
__u64 next;
__u32 type;
__u32 len;
- __u8 data[0];
+ __u8 data[];
};
struct setup_indirect {
__u32 type;
@@ -147,6 +151,10 @@
__u32 flags;
} __attribute__((packed)) v2;
} __attribute__((packed));
+struct ima_setup_data {
+ __u64 addr;
+ __u64 size;
+} __attribute__((packed));
struct boot_params {
struct screen_info screen_info;
struct apm_bios_info apm_bios_info;
@@ -162,7 +170,8 @@
__u32 ext_ramdisk_image;
__u32 ext_ramdisk_size;
__u32 ext_cmd_line_ptr;
- __u8 _pad4[116];
+ __u8 _pad4[112];
+ __u32 cc_blob_address;
struct edid_info edid_info;
struct efi_info efi_info;
__u32 alt_mem_k;
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index caf8fc0..f07b00e 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -178,11 +178,11 @@
struct kvm_msrs {
__u32 nmsrs;
__u32 pad;
- struct kvm_msr_entry entries[0];
+ struct kvm_msr_entry entries[];
};
struct kvm_msr_list {
__u32 nmsrs;
- __u32 indices[0];
+ __u32 indices[];
};
#define KVM_MSR_FILTER_MAX_BITMAP_SIZE 0x600
struct kvm_msr_filter_range {
@@ -211,7 +211,7 @@
struct kvm_cpuid {
__u32 nent;
__u32 padding;
- struct kvm_cpuid_entry entries[0];
+ struct kvm_cpuid_entry entries[];
};
struct kvm_cpuid_entry2 {
__u32 function;
@@ -229,7 +229,7 @@
struct kvm_cpuid2 {
__u32 nent;
__u32 padding;
- struct kvm_cpuid_entry2 entries[0];
+ struct kvm_cpuid_entry2 entries[];
};
struct kvm_pit_channel_state {
__u32 count;
@@ -265,6 +265,7 @@
struct kvm_pit_channel_state channels[3];
};
#define KVM_PIT_FLAGS_HPET_LEGACY 0x00000001
+#define KVM_PIT_FLAGS_SPEAKER_DATA_ON 0x00000002
struct kvm_pit_state2 {
struct kvm_pit_channel_state channels[3];
__u32 flags;
@@ -279,6 +280,7 @@
#define KVM_VCPUEVENT_VALID_SHADOW 0x00000004
#define KVM_VCPUEVENT_VALID_SMM 0x00000008
#define KVM_VCPUEVENT_VALID_PAYLOAD 0x00000010
+#define KVM_VCPUEVENT_VALID_TRIPLE_FAULT 0x00000020
#define KVM_X86_SHADOW_INT_MOV_SS 0x01
#define KVM_X86_SHADOW_INT_STI 0x02
struct kvm_vcpu_events {
@@ -309,7 +311,10 @@
__u8 smm_inside_nmi;
__u8 latched_init;
} smi;
- __u8 reserved[27];
+ struct {
+ __u8 pending;
+ } triple_fault;
+ __u8 reserved[26];
__u8 exception_has_payload;
__u64 exception_payload;
};
@@ -322,7 +327,7 @@
};
struct kvm_xsave {
__u32 region[1024];
- __u32 extra[0];
+ __u32 extra[];
};
#define KVM_MAX_XCRS 16
struct kvm_xcr {
@@ -350,6 +355,8 @@
#define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2)
#define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3)
#define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT (1 << 4)
+#define KVM_X86_QUIRK_FIX_HYPERCALL_INSN (1 << 5)
+#define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6)
#define KVM_STATE_NESTED_FORMAT_VMX 0
#define KVM_STATE_NESTED_FORMAT_SVM 1
#define KVM_STATE_NESTED_GUEST_MODE 0x00000001
@@ -403,7 +410,7 @@
__u32 fixed_counter_bitmap;
__u32 flags;
__u32 pad[4];
- __u64 events[0];
+ __u64 events[];
};
#define KVM_PMU_EVENT_ALLOW 0
#define KVM_PMU_EVENT_DENY 1
diff --git a/libc/kernel/uapi/asm-x86/asm/processor-flags.h b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
index 85f9d7e..0a95afd 100644
--- a/libc/kernel/uapi/asm-x86/asm/processor-flags.h
+++ b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
@@ -127,6 +127,8 @@
#define X86_CR4_SMAP _BITUL(X86_CR4_SMAP_BIT)
#define X86_CR4_PKE_BIT 22
#define X86_CR4_PKE _BITUL(X86_CR4_PKE_BIT)
+#define X86_CR4_CET_BIT 23
+#define X86_CR4_CET _BITUL(X86_CR4_CET_BIT)
#define X86_CR8_TPR _AC(0x0000000f, UL)
#define CX86_PCR0 0x20
#define CX86_GCR 0xb8
diff --git a/libc/kernel/uapi/asm-x86/asm/sgx.h b/libc/kernel/uapi/asm-x86/asm/sgx.h
index 1874b78..fdc2700 100644
--- a/libc/kernel/uapi/asm-x86/asm/sgx.h
+++ b/libc/kernel/uapi/asm-x86/asm/sgx.h
@@ -29,6 +29,9 @@
#define SGX_IOC_ENCLAVE_INIT _IOW(SGX_MAGIC, 0x02, struct sgx_enclave_init)
#define SGX_IOC_ENCLAVE_PROVISION _IOW(SGX_MAGIC, 0x03, struct sgx_enclave_provision)
#define SGX_IOC_VEPC_REMOVE_ALL _IO(SGX_MAGIC, 0x04)
+#define SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS _IOWR(SGX_MAGIC, 0x05, struct sgx_enclave_restrict_permissions)
+#define SGX_IOC_ENCLAVE_MODIFY_TYPES _IOWR(SGX_MAGIC, 0x06, struct sgx_enclave_modify_types)
+#define SGX_IOC_ENCLAVE_REMOVE_PAGES _IOWR(SGX_MAGIC, 0x07, struct sgx_enclave_remove_pages)
struct sgx_enclave_create {
__u64 src;
};
@@ -46,6 +49,25 @@
struct sgx_enclave_provision {
__u64 fd;
};
+struct sgx_enclave_restrict_permissions {
+ __u64 offset;
+ __u64 length;
+ __u64 permissions;
+ __u64 result;
+ __u64 count;
+};
+struct sgx_enclave_modify_types {
+ __u64 offset;
+ __u64 length;
+ __u64 page_type;
+ __u64 result;
+ __u64 count;
+};
+struct sgx_enclave_remove_pages {
+ __u64 offset;
+ __u64 length;
+ __u64 count;
+};
struct sgx_enclave_run;
typedef int(* sgx_enclave_user_handler_t) (long rdi, long rsi, long rdx, long rsp, long r8, long r9, struct sgx_enclave_run * run);
struct sgx_enclave_run {
diff --git a/libc/kernel/uapi/asm-x86/asm/shmbuf.h b/libc/kernel/uapi/asm-x86/asm/shmbuf.h
index 03e195e..2a0dcb5 100644
--- a/libc/kernel/uapi/asm-x86/asm/shmbuf.h
+++ b/libc/kernel/uapi/asm-x86/asm/shmbuf.h
@@ -21,9 +21,11 @@
#if !defined(__x86_64__) || !defined(__ILP32__)
#include <asm-generic/shmbuf.h>
#else
+#include <asm/ipcbuf.h>
+#include <asm/posix_types.h>
struct shmid64_ds {
struct ipc64_perm shm_perm;
- size_t shm_segsz;
+ __kernel_size_t shm_segsz;
__kernel_long_t shm_atime;
__kernel_long_t shm_dtime;
__kernel_long_t shm_ctime;
diff --git a/libc/kernel/uapi/asm-x86/asm/signal.h b/libc/kernel/uapi/asm-x86/asm/signal.h
index 8226da8..cbeeac4 100644
--- a/libc/kernel/uapi/asm-x86/asm/signal.h
+++ b/libc/kernel/uapi/asm-x86/asm/signal.h
@@ -90,7 +90,7 @@
typedef struct sigaltstack {
void __user * ss_sp;
int ss_flags;
- size_t ss_size;
+ __kernel_size_t ss_size;
} stack_t;
#endif
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/svm.h b/libc/kernel/uapi/asm-x86/asm/svm.h
index d051481..8bda2d5 100644
--- a/libc/kernel/uapi/asm-x86/asm/svm.h
+++ b/libc/kernel/uapi/asm-x86/asm/svm.h
@@ -122,8 +122,16 @@
#define SVM_VMGEXIT_AP_JUMP_TABLE 0x80000005
#define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0
#define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1
+#define SVM_VMGEXIT_PSC 0x80000010
+#define SVM_VMGEXIT_GUEST_REQUEST 0x80000011
+#define SVM_VMGEXIT_EXT_GUEST_REQUEST 0x80000012
+#define SVM_VMGEXIT_AP_CREATION 0x80000013
+#define SVM_VMGEXIT_AP_CREATE_ON_INIT 0
+#define SVM_VMGEXIT_AP_CREATE 1
+#define SVM_VMGEXIT_AP_DESTROY 2
+#define SVM_VMGEXIT_HV_FEATURES 0x8000fffd
#define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff
#define SVM_EXIT_SW 0xf0000000
#define SVM_EXIT_ERR - 1
-#define SVM_EXIT_REASONS { SVM_EXIT_READ_CR0, "read_cr0" }, { SVM_EXIT_READ_CR2, "read_cr2" }, { SVM_EXIT_READ_CR3, "read_cr3" }, { SVM_EXIT_READ_CR4, "read_cr4" }, { SVM_EXIT_READ_CR8, "read_cr8" }, { SVM_EXIT_WRITE_CR0, "write_cr0" }, { SVM_EXIT_WRITE_CR2, "write_cr2" }, { SVM_EXIT_WRITE_CR3, "write_cr3" }, { SVM_EXIT_WRITE_CR4, "write_cr4" }, { SVM_EXIT_WRITE_CR8, "write_cr8" }, { SVM_EXIT_READ_DR0, "read_dr0" }, { SVM_EXIT_READ_DR1, "read_dr1" }, { SVM_EXIT_READ_DR2, "read_dr2" }, { SVM_EXIT_READ_DR3, "read_dr3" }, { SVM_EXIT_READ_DR4, "read_dr4" }, { SVM_EXIT_READ_DR5, "read_dr5" }, { SVM_EXIT_READ_DR6, "read_dr6" }, { SVM_EXIT_READ_DR7, "read_dr7" }, { SVM_EXIT_WRITE_DR0, "write_dr0" }, { SVM_EXIT_WRITE_DR1, "write_dr1" }, { SVM_EXIT_WRITE_DR2, "write_dr2" }, { SVM_EXIT_WRITE_DR3, "write_dr3" }, { SVM_EXIT_WRITE_DR4, "write_dr4" }, { SVM_EXIT_WRITE_DR5, "write_dr5" }, { SVM_EXIT_WRITE_DR6, "write_dr6" }, { SVM_EXIT_WRITE_DR7, "write_dr7" }, { SVM_EXIT_EXCP_BASE + DE_VECTOR, "DE excp" }, { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, { SVM_EXIT_EXCP_BASE + OF_VECTOR, "OF excp" }, { SVM_EXIT_EXCP_BASE + BR_VECTOR, "BR excp" }, { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, { SVM_EXIT_EXCP_BASE + DF_VECTOR, "DF excp" }, { SVM_EXIT_EXCP_BASE + TS_VECTOR, "TS excp" }, { SVM_EXIT_EXCP_BASE + NP_VECTOR, "NP excp" }, { SVM_EXIT_EXCP_BASE + SS_VECTOR, "SS excp" }, { SVM_EXIT_EXCP_BASE + GP_VECTOR, "GP excp" }, { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, { SVM_EXIT_EXCP_BASE + MF_VECTOR, "MF excp" }, { SVM_EXIT_EXCP_BASE + AC_VECTOR, "AC excp" }, { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, { SVM_EXIT_EXCP_BASE + XM_VECTOR, "XF excp" }, { SVM_EXIT_INTR, "interrupt" }, { SVM_EXIT_NMI, "nmi" }, { SVM_EXIT_SMI, "smi" }, { SVM_EXIT_INIT, "init" }, { SVM_EXIT_VINTR, "vintr" }, { SVM_EXIT_CR0_SEL_WRITE, "cr0_sel_write" }, { SVM_EXIT_IDTR_READ, "read_idtr" }, { SVM_EXIT_GDTR_READ, "read_gdtr" }, { SVM_EXIT_LDTR_READ, "read_ldtr" }, { SVM_EXIT_TR_READ, "read_rt" }, { SVM_EXIT_IDTR_WRITE, "write_idtr" }, { SVM_EXIT_GDTR_WRITE, "write_gdtr" }, { SVM_EXIT_LDTR_WRITE, "write_ldtr" }, { SVM_EXIT_TR_WRITE, "write_rt" }, { SVM_EXIT_RDTSC, "rdtsc" }, { SVM_EXIT_RDPMC, "rdpmc" }, { SVM_EXIT_PUSHF, "pushf" }, { SVM_EXIT_POPF, "popf" }, { SVM_EXIT_CPUID, "cpuid" }, { SVM_EXIT_RSM, "rsm" }, { SVM_EXIT_IRET, "iret" }, { SVM_EXIT_SWINT, "swint" }, { SVM_EXIT_INVD, "invd" }, { SVM_EXIT_PAUSE, "pause" }, { SVM_EXIT_HLT, "hlt" }, { SVM_EXIT_INVLPG, "invlpg" }, { SVM_EXIT_INVLPGA, "invlpga" }, { SVM_EXIT_IOIO, "io" }, { SVM_EXIT_MSR, "msr" }, { SVM_EXIT_TASK_SWITCH, "task_switch" }, { SVM_EXIT_FERR_FREEZE, "ferr_freeze" }, { SVM_EXIT_SHUTDOWN, "shutdown" }, { SVM_EXIT_VMRUN, "vmrun" }, { SVM_EXIT_VMMCALL, "hypercall" }, { SVM_EXIT_VMLOAD, "vmload" }, { SVM_EXIT_VMSAVE, "vmsave" }, { SVM_EXIT_STGI, "stgi" }, { SVM_EXIT_CLGI, "clgi" }, { SVM_EXIT_SKINIT, "skinit" }, { SVM_EXIT_RDTSCP, "rdtscp" }, { SVM_EXIT_ICEBP, "icebp" }, { SVM_EXIT_WBINVD, "wbinvd" }, { SVM_EXIT_MONITOR, "monitor" }, { SVM_EXIT_MWAIT, "mwait" }, { SVM_EXIT_XSETBV, "xsetbv" }, { SVM_EXIT_EFER_WRITE_TRAP, "write_efer_trap" }, { SVM_EXIT_CR0_WRITE_TRAP, "write_cr0_trap" }, { SVM_EXIT_CR4_WRITE_TRAP, "write_cr4_trap" }, { SVM_EXIT_CR8_WRITE_TRAP, "write_cr8_trap" }, { SVM_EXIT_INVPCID, "invpcid" }, { SVM_EXIT_NPF, "npf" }, { SVM_EXIT_AVIC_INCOMPLETE_IPI, "avic_incomplete_ipi" }, { SVM_EXIT_AVIC_UNACCELERATED_ACCESS, "avic_unaccelerated_access" }, { SVM_EXIT_VMGEXIT, "vmgexit" }, { SVM_VMGEXIT_MMIO_READ, "vmgexit_mmio_read" }, { SVM_VMGEXIT_MMIO_WRITE, "vmgexit_mmio_write" }, { SVM_VMGEXIT_NMI_COMPLETE, "vmgexit_nmi_complete" }, { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, { SVM_EXIT_ERR, "invalid_guest_state" }
+#define SVM_EXIT_REASONS { SVM_EXIT_READ_CR0, "read_cr0" }, { SVM_EXIT_READ_CR2, "read_cr2" }, { SVM_EXIT_READ_CR3, "read_cr3" }, { SVM_EXIT_READ_CR4, "read_cr4" }, { SVM_EXIT_READ_CR8, "read_cr8" }, { SVM_EXIT_WRITE_CR0, "write_cr0" }, { SVM_EXIT_WRITE_CR2, "write_cr2" }, { SVM_EXIT_WRITE_CR3, "write_cr3" }, { SVM_EXIT_WRITE_CR4, "write_cr4" }, { SVM_EXIT_WRITE_CR8, "write_cr8" }, { SVM_EXIT_READ_DR0, "read_dr0" }, { SVM_EXIT_READ_DR1, "read_dr1" }, { SVM_EXIT_READ_DR2, "read_dr2" }, { SVM_EXIT_READ_DR3, "read_dr3" }, { SVM_EXIT_READ_DR4, "read_dr4" }, { SVM_EXIT_READ_DR5, "read_dr5" }, { SVM_EXIT_READ_DR6, "read_dr6" }, { SVM_EXIT_READ_DR7, "read_dr7" }, { SVM_EXIT_WRITE_DR0, "write_dr0" }, { SVM_EXIT_WRITE_DR1, "write_dr1" }, { SVM_EXIT_WRITE_DR2, "write_dr2" }, { SVM_EXIT_WRITE_DR3, "write_dr3" }, { SVM_EXIT_WRITE_DR4, "write_dr4" }, { SVM_EXIT_WRITE_DR5, "write_dr5" }, { SVM_EXIT_WRITE_DR6, "write_dr6" }, { SVM_EXIT_WRITE_DR7, "write_dr7" }, { SVM_EXIT_EXCP_BASE + DE_VECTOR, "DE excp" }, { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, { SVM_EXIT_EXCP_BASE + OF_VECTOR, "OF excp" }, { SVM_EXIT_EXCP_BASE + BR_VECTOR, "BR excp" }, { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, { SVM_EXIT_EXCP_BASE + DF_VECTOR, "DF excp" }, { SVM_EXIT_EXCP_BASE + TS_VECTOR, "TS excp" }, { SVM_EXIT_EXCP_BASE + NP_VECTOR, "NP excp" }, { SVM_EXIT_EXCP_BASE + SS_VECTOR, "SS excp" }, { SVM_EXIT_EXCP_BASE + GP_VECTOR, "GP excp" }, { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, { SVM_EXIT_EXCP_BASE + MF_VECTOR, "MF excp" }, { SVM_EXIT_EXCP_BASE + AC_VECTOR, "AC excp" }, { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, { SVM_EXIT_EXCP_BASE + XM_VECTOR, "XF excp" }, { SVM_EXIT_INTR, "interrupt" }, { SVM_EXIT_NMI, "nmi" }, { SVM_EXIT_SMI, "smi" }, { SVM_EXIT_INIT, "init" }, { SVM_EXIT_VINTR, "vintr" }, { SVM_EXIT_CR0_SEL_WRITE, "cr0_sel_write" }, { SVM_EXIT_IDTR_READ, "read_idtr" }, { SVM_EXIT_GDTR_READ, "read_gdtr" }, { SVM_EXIT_LDTR_READ, "read_ldtr" }, { SVM_EXIT_TR_READ, "read_rt" }, { SVM_EXIT_IDTR_WRITE, "write_idtr" }, { SVM_EXIT_GDTR_WRITE, "write_gdtr" }, { SVM_EXIT_LDTR_WRITE, "write_ldtr" }, { SVM_EXIT_TR_WRITE, "write_rt" }, { SVM_EXIT_RDTSC, "rdtsc" }, { SVM_EXIT_RDPMC, "rdpmc" }, { SVM_EXIT_PUSHF, "pushf" }, { SVM_EXIT_POPF, "popf" }, { SVM_EXIT_CPUID, "cpuid" }, { SVM_EXIT_RSM, "rsm" }, { SVM_EXIT_IRET, "iret" }, { SVM_EXIT_SWINT, "swint" }, { SVM_EXIT_INVD, "invd" }, { SVM_EXIT_PAUSE, "pause" }, { SVM_EXIT_HLT, "hlt" }, { SVM_EXIT_INVLPG, "invlpg" }, { SVM_EXIT_INVLPGA, "invlpga" }, { SVM_EXIT_IOIO, "io" }, { SVM_EXIT_MSR, "msr" }, { SVM_EXIT_TASK_SWITCH, "task_switch" }, { SVM_EXIT_FERR_FREEZE, "ferr_freeze" }, { SVM_EXIT_SHUTDOWN, "shutdown" }, { SVM_EXIT_VMRUN, "vmrun" }, { SVM_EXIT_VMMCALL, "hypercall" }, { SVM_EXIT_VMLOAD, "vmload" }, { SVM_EXIT_VMSAVE, "vmsave" }, { SVM_EXIT_STGI, "stgi" }, { SVM_EXIT_CLGI, "clgi" }, { SVM_EXIT_SKINIT, "skinit" }, { SVM_EXIT_RDTSCP, "rdtscp" }, { SVM_EXIT_ICEBP, "icebp" }, { SVM_EXIT_WBINVD, "wbinvd" }, { SVM_EXIT_MONITOR, "monitor" }, { SVM_EXIT_MWAIT, "mwait" }, { SVM_EXIT_XSETBV, "xsetbv" }, { SVM_EXIT_EFER_WRITE_TRAP, "write_efer_trap" }, { SVM_EXIT_CR0_WRITE_TRAP, "write_cr0_trap" }, { SVM_EXIT_CR4_WRITE_TRAP, "write_cr4_trap" }, { SVM_EXIT_CR8_WRITE_TRAP, "write_cr8_trap" }, { SVM_EXIT_INVPCID, "invpcid" }, { SVM_EXIT_NPF, "npf" }, { SVM_EXIT_AVIC_INCOMPLETE_IPI, "avic_incomplete_ipi" }, { SVM_EXIT_AVIC_UNACCELERATED_ACCESS, "avic_unaccelerated_access" }, { SVM_EXIT_VMGEXIT, "vmgexit" }, { SVM_VMGEXIT_MMIO_READ, "vmgexit_mmio_read" }, { SVM_VMGEXIT_MMIO_WRITE, "vmgexit_mmio_write" }, { SVM_VMGEXIT_NMI_COMPLETE, "vmgexit_nmi_complete" }, { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, { SVM_VMGEXIT_PSC, "vmgexit_page_state_change" }, { SVM_VMGEXIT_GUEST_REQUEST, "vmgexit_guest_request" }, { SVM_VMGEXIT_EXT_GUEST_REQUEST, "vmgexit_ext_guest_request" }, { SVM_VMGEXIT_AP_CREATION, "vmgexit_ap_creation" }, { SVM_VMGEXIT_HV_FEATURES, "vmgexit_hypervisor_feature" }, { SVM_EXIT_ERR, "invalid_guest_state" }
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/vmx.h b/libc/kernel/uapi/asm-x86/asm/vmx.h
index 6c07d4c..fdea539 100644
--- a/libc/kernel/uapi/asm-x86/asm/vmx.h
+++ b/libc/kernel/uapi/asm-x86/asm/vmx.h
@@ -81,7 +81,8 @@
#define EXIT_REASON_UMWAIT 67
#define EXIT_REASON_TPAUSE 68
#define EXIT_REASON_BUS_LOCK 74
-#define VMX_EXIT_REASONS { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, { EXIT_REASON_INIT_SIGNAL, "INIT_SIGNAL" }, { EXIT_REASON_SIPI_SIGNAL, "SIPI_SIGNAL" }, { EXIT_REASON_INTERRUPT_WINDOW, "INTERRUPT_WINDOW" }, { 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" }, { EXIT_REASON_UMWAIT, "UMWAIT" }, { EXIT_REASON_TPAUSE, "TPAUSE" }, { EXIT_REASON_BUS_LOCK, "BUS_LOCK" }
+#define EXIT_REASON_NOTIFY 75
+#define VMX_EXIT_REASONS { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, { EXIT_REASON_INIT_SIGNAL, "INIT_SIGNAL" }, { EXIT_REASON_SIPI_SIGNAL, "SIPI_SIGNAL" }, { EXIT_REASON_INTERRUPT_WINDOW, "INTERRUPT_WINDOW" }, { 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" }, { EXIT_REASON_UMWAIT, "UMWAIT" }, { EXIT_REASON_TPAUSE, "TPAUSE" }, { EXIT_REASON_BUS_LOCK, "BUS_LOCK" }, { EXIT_REASON_NOTIFY, "NOTIFY" }
#define VMX_EXIT_REASON_FLAGS { VMX_EXIT_REASONS_FAILED_VMENTRY, "FAILED_VMENTRY" }
#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1
#define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index 3764d51..f03a086 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -72,6 +72,7 @@
#define AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE (1 << 9)
#define AMDGPU_GEM_CREATE_ENCRYPTED (1 << 10)
#define AMDGPU_GEM_CREATE_PREEMPTIBLE (1 << 11)
+#define AMDGPU_GEM_CREATE_DISCARDABLE (1 << 12)
struct drm_amdgpu_gem_create_in {
__u64 bo_size;
__u64 alignment;
@@ -112,6 +113,8 @@
#define AMDGPU_CTX_OP_FREE_CTX 2
#define AMDGPU_CTX_OP_QUERY_STATE 3
#define AMDGPU_CTX_OP_QUERY_STATE2 4
+#define AMDGPU_CTX_OP_GET_STABLE_PSTATE 5
+#define AMDGPU_CTX_OP_SET_STABLE_PSTATE 6
#define AMDGPU_CTX_NO_RESET 0
#define AMDGPU_CTX_GUILTY_RESET 1
#define AMDGPU_CTX_INNOCENT_RESET 2
@@ -127,6 +130,12 @@
#define AMDGPU_CTX_PRIORITY_NORMAL 0
#define AMDGPU_CTX_PRIORITY_HIGH 512
#define AMDGPU_CTX_PRIORITY_VERY_HIGH 1023
+#define AMDGPU_CTX_STABLE_PSTATE_FLAGS_MASK 0xf
+#define AMDGPU_CTX_STABLE_PSTATE_NONE 0
+#define AMDGPU_CTX_STABLE_PSTATE_STANDARD 1
+#define AMDGPU_CTX_STABLE_PSTATE_MIN_SCLK 2
+#define AMDGPU_CTX_STABLE_PSTATE_MIN_MCLK 3
+#define AMDGPU_CTX_STABLE_PSTATE_PEAK 4
struct drm_amdgpu_ctx_in {
__u32 op;
__u32 flags;
@@ -143,6 +152,10 @@
__u32 hangs;
__u32 reset_status;
} state;
+ struct {
+ __u32 flags;
+ __u32 _pad;
+ } pstate;
};
union drm_amdgpu_ctx {
struct drm_amdgpu_ctx_in in;
@@ -307,6 +320,7 @@
#define AMDGPU_VM_MTYPE_CC (3 << 5)
#define AMDGPU_VM_MTYPE_UC (4 << 5)
#define AMDGPU_VM_MTYPE_RW (5 << 5)
+#define AMDGPU_VM_PAGE_NOALLOC (1 << 9)
struct drm_amdgpu_gem_va {
__u32 handle;
__u32 _pad;
@@ -438,6 +452,7 @@
#define AMDGPU_INFO_FW_TA 0x13
#define AMDGPU_INFO_FW_DMCUB 0x14
#define AMDGPU_INFO_FW_TOC 0x15
+#define AMDGPU_INFO_FW_CAP 0x16
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
#define AMDGPU_INFO_VRAM_USAGE 0x10
#define AMDGPU_INFO_GTT_USAGE 0x11
@@ -575,6 +590,8 @@
#define AMDGPU_VRAM_TYPE_DDR4 8
#define AMDGPU_VRAM_TYPE_GDDR6 9
#define AMDGPU_VRAM_TYPE_DDR5 10
+#define AMDGPU_VRAM_TYPE_LPDDR4 11
+#define AMDGPU_VRAM_TYPE_LPDDR5 12
struct drm_amdgpu_info_device {
__u32 device_id;
__u32 chip_rev;
@@ -633,7 +650,7 @@
__u32 ib_start_alignment;
__u32 ib_size_alignment;
__u32 available_rings;
- __u32 _pad;
+ __u32 ip_discovery_version;
};
struct drm_amdgpu_info_num_handles {
__u32 uvd_max_handles;
@@ -681,7 +698,11 @@
#define AMDGPU_FAMILY_RV 142
#define AMDGPU_FAMILY_NV 143
#define AMDGPU_FAMILY_VGH 144
+#define AMDGPU_FAMILY_GC_11_0_0 145
#define AMDGPU_FAMILY_YC 146
+#define AMDGPU_FAMILY_GC_11_0_1 148
+#define AMDGPU_FAMILY_GC_10_3_6 149
+#define AMDGPU_FAMILY_GC_10_3_7 151
#ifdef __cplusplus
}
#endif
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index e845c8c..a59a6fb 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -163,9 +163,15 @@
#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS fourcc_mod_code(INTEL, 6)
#define I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS fourcc_mod_code(INTEL, 7)
#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC fourcc_mod_code(INTEL, 8)
+#define I915_FORMAT_MOD_4_TILED fourcc_mod_code(INTEL, 9)
+#define I915_FORMAT_MOD_4_TILED_DG2_RC_CCS fourcc_mod_code(INTEL, 10)
+#define I915_FORMAT_MOD_4_TILED_DG2_MC_CCS fourcc_mod_code(INTEL, 11)
+#define I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC fourcc_mod_code(INTEL, 12)
#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
#define DRM_FORMAT_MOD_SAMSUNG_16_16_TILE fourcc_mod_code(SAMSUNG, 2)
#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
+#define DRM_FORMAT_MOD_QCOM_TILED3 fourcc_mod_code(QCOM, 3)
+#define DRM_FORMAT_MOD_QCOM_TILED2 fourcc_mod_code(QCOM, 2)
#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)
@@ -235,11 +241,13 @@
#define AMD_FMT_MOD_TILE_VER_GFX9 1
#define AMD_FMT_MOD_TILE_VER_GFX10 2
#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
+#define AMD_FMT_MOD_TILE_VER_GFX11 4
#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
+#define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31
#define AMD_FMT_MOD_DCC_BLOCK_64B 0
#define AMD_FMT_MOD_DCC_BLOCK_128B 1
#define AMD_FMT_MOD_DCC_BLOCK_256B 2
@@ -271,9 +279,9 @@
#define AMD_FMT_MOD_RB_MASK 0x7
#define AMD_FMT_MOD_PIPE_SHIFT 33
#define AMD_FMT_MOD_PIPE_MASK 0x7
-#define AMD_FMT_MOD_SET(field,value) ((uint64_t) (value) << AMD_FMT_MOD_ ##field ##_SHIFT)
+#define AMD_FMT_MOD_SET(field,value) ((__u64) (value) << AMD_FMT_MOD_ ##field ##_SHIFT)
#define AMD_FMT_MOD_GET(field,value) (((value) >> AMD_FMT_MOD_ ##field ##_SHIFT) & AMD_FMT_MOD_ ##field ##_MASK)
-#define AMD_FMT_MOD_CLEAR(field) (~((uint64_t) AMD_FMT_MOD_ ##field ##_MASK << AMD_FMT_MOD_ ##field ##_SHIFT))
+#define AMD_FMT_MOD_CLEAR(field) (~((__u64) AMD_FMT_MOD_ ##field ##_MASK << AMD_FMT_MOD_ ##field ##_SHIFT))
#ifdef __cplusplus
}
#endif
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 52bfad2..3188908 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -41,13 +41,14 @@
I915_ENGINE_CLASS_COPY = 1,
I915_ENGINE_CLASS_VIDEO = 2,
I915_ENGINE_CLASS_VIDEO_ENHANCE = 3,
+ I915_ENGINE_CLASS_COMPUTE = 4,
I915_ENGINE_CLASS_INVALID = - 1
};
struct i915_engine_class_instance {
__u16 engine_class;
- __u16 engine_instance;
#define I915_ENGINE_CLASS_INVALID_NONE - 1
#define I915_ENGINE_CLASS_INVALID_VIRTUAL - 2
+ __u16 engine_instance;
};
enum drm_i915_pmu_engine_sample {
I915_SAMPLE_BUSY = 0,
@@ -367,10 +368,11 @@
#define I915_PARAM_PERF_REVISION 54
#define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
#define I915_PARAM_HAS_USERPTR_PROBE 56
-typedef struct drm_i915_getparam {
+struct drm_i915_getparam {
__s32 param;
int __user * value;
-} drm_i915_getparam_t;
+};
+typedef struct drm_i915_getparam drm_i915_getparam_t;
#define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1
#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2
#define I915_SETPARAM_ALLOW_BATCHBUFFER 3
@@ -525,13 +527,13 @@
};
struct drm_i915_gem_exec_fence {
__u32 handle;
+ __u32 flags;
#define I915_EXEC_FENCE_WAIT (1 << 0)
#define I915_EXEC_FENCE_SIGNAL (1 << 1)
#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (- (I915_EXEC_FENCE_SIGNAL << 1))
- __u32 flags;
};
-#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
struct drm_i915_gem_execbuffer_ext_timeline_fences {
+#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
struct i915_user_extension base;
__u64 fence_count;
__u64 handles_ptr;
@@ -546,6 +548,7 @@
__u32 DR4;
__u32 num_cliprects;
__u64 cliprects_ptr;
+ __u64 flags;
#define I915_EXEC_RING_MASK (0x3f)
#define I915_EXEC_DEFAULT (0 << 0)
#define I915_EXEC_RENDER (1 << 0)
@@ -556,10 +559,6 @@
#define I915_EXEC_CONSTANTS_REL_GENERAL (0 << 6)
#define I915_EXEC_CONSTANTS_ABSOLUTE (1 << 6)
#define I915_EXEC_CONSTANTS_REL_SURFACE (2 << 6)
- __u64 flags;
- __u64 rsvd1;
- __u64 rsvd2;
-};
#define I915_EXEC_GEN7_SOL_RESET (1 << 8)
#define I915_EXEC_SECURE (1 << 9)
#define I915_EXEC_IS_PINNED (1 << 10)
@@ -578,6 +577,9 @@
#define I915_EXEC_FENCE_SUBMIT (1 << 20)
#define I915_EXEC_USE_EXTENSIONS (1 << 21)
#define __I915_EXEC_UNKNOWN_FLAGS (- (I915_EXEC_USE_EXTENSIONS << 1))
+ __u64 rsvd1;
+ __u64 rsvd2;
+};
#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)
@@ -721,6 +723,8 @@
#define I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE (1u << 1)
#define I915_CONTEXT_CREATE_FLAGS_UNKNOWN (- (I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE << 1))
__u64 extensions;
+#define I915_CONTEXT_CREATE_EXT_SETPARAM 0
+#define I915_CONTEXT_CREATE_EXT_CLONE 1
};
struct drm_i915_gem_context_param {
__u32 ctx_id;
@@ -760,7 +764,7 @@
__u16 num_siblings;
__u32 flags;
__u64 mbz64;
- struct i915_engine_class_instance engines[0];
+ struct i915_engine_class_instance engines[];
} __attribute__((packed));
#define I915_DEFINE_CONTEXT_ENGINES_LOAD_BALANCE(name__,N__) struct { struct i915_user_extension base; __u16 engine_index; __u16 num_siblings; __u32 flags; __u64 mbz64; struct i915_engine_class_instance engines[N__]; \
} __attribute__((packed)) name__
@@ -771,7 +775,7 @@
__u16 num_bonds;
__u64 flags;
__u64 mbz64[4];
- struct i915_engine_class_instance engines[0];
+ struct i915_engine_class_instance engines[];
} __attribute__((packed));
#define I915_DEFINE_CONTEXT_ENGINES_BOND(name__,N__) struct { struct i915_user_extension base; struct i915_engine_class_instance master; __u16 virtual_index; __u16 num_bonds; __u64 flags; __u64 mbz64[4]; struct i915_engine_class_instance engines[N__]; \
} __attribute__((packed)) name__
@@ -783,7 +787,7 @@
__u16 mbz16;
__u64 flags;
__u64 mbz64[3];
- struct i915_engine_class_instance engines[0];
+ struct i915_engine_class_instance engines[];
} __packed;
#define I915_DEFINE_CONTEXT_ENGINES_PARALLEL_SUBMIT(name__,N__) struct { struct i915_user_extension base; __u16 engine_index; __u16 width; __u16 num_siblings; __u16 mbz16; __u64 flags; __u64 mbz64[3]; struct i915_engine_class_instance engines[N__]; \
} __attribute__((packed)) name__
@@ -797,11 +801,9 @@
#define I915_DEFINE_CONTEXT_PARAM_ENGINES(name__,N__) struct { __u64 extensions; struct i915_engine_class_instance engines[N__]; \
} __attribute__((packed)) name__
struct drm_i915_gem_context_create_ext_setparam {
-#define I915_CONTEXT_CREATE_EXT_SETPARAM 0
struct i915_user_extension base;
struct drm_i915_gem_context_param param;
};
-#define I915_CONTEXT_CREATE_EXT_CLONE 1
struct drm_i915_gem_context_destroy {
__u32 ctx_id;
__u32 pad;
@@ -894,6 +896,8 @@
#define DRM_I915_QUERY_ENGINE_INFO 2
#define DRM_I915_QUERY_PERF_CONFIG 3
#define DRM_I915_QUERY_MEMORY_REGIONS 4
+#define DRM_I915_QUERY_HWCONFIG_BLOB 5
+#define DRM_I915_QUERY_GEOMETRY_SUBSLICES 6
__s32 length;
__u32 flags;
#define DRM_I915_QUERY_PERF_CONFIG_LIST 1
@@ -956,7 +960,13 @@
__u32 rsvd0;
__u64 probed_size;
__u64 unallocated_size;
- __u64 rsvd1[8];
+ union {
+ __u64 rsvd1[8];
+ struct {
+ __u64 probed_cpu_visible_size;
+ __u64 unallocated_cpu_visible_size;
+ };
+ };
};
struct drm_i915_query_memory_regions {
__u32 num_regions;
@@ -966,6 +976,7 @@
struct drm_i915_gem_create_ext {
__u64 size;
__u32 handle;
+#define I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS (1 << 0)
__u32 flags;
#define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index b4ba1d0..c2edefd 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -43,11 +43,18 @@
#define MSM_PARAM_PP_PGTABLE 0x08
#define MSM_PARAM_FAULTS 0x09
#define MSM_PARAM_SUSPENDS 0x0a
+#define MSM_PARAM_SYSPROF 0x0b
+#define MSM_PARAM_COMM 0x0c
+#define MSM_PARAM_CMDLINE 0x0d
+#define MSM_PARAM_VA_START 0x0e
+#define MSM_PARAM_VA_SIZE 0x0f
#define MSM_PARAM_NR_RINGS MSM_PARAM_PRIORITIES
struct drm_msm_param {
__u32 pipe;
__u32 param;
__u64 value;
+ __u32 len;
+ __u32 pad;
};
#define MSM_BO_SCANOUT 0x00000001
#define MSM_BO_GPU_READONLY 0x00000002
@@ -66,6 +73,7 @@
#define MSM_INFO_GET_IOVA 0x01
#define MSM_INFO_SET_NAME 0x02
#define MSM_INFO_GET_NAME 0x03
+#define MSM_INFO_SET_IOVA 0x04
struct drm_msm_gem_info {
__u32 handle;
__u32 info;
@@ -119,7 +127,8 @@
#define MSM_SUBMIT_SUDO 0x10000000
#define MSM_SUBMIT_SYNCOBJ_IN 0x08000000
#define MSM_SUBMIT_SYNCOBJ_OUT 0x04000000
-#define MSM_SUBMIT_FLAGS (MSM_SUBMIT_NO_IMPLICIT | MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_FENCE_FD_OUT | MSM_SUBMIT_SUDO | MSM_SUBMIT_SYNCOBJ_IN | MSM_SUBMIT_SYNCOBJ_OUT | 0)
+#define MSM_SUBMIT_FENCE_SN_IN 0x02000000
+#define MSM_SUBMIT_FLAGS (MSM_SUBMIT_NO_IMPLICIT | MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_FENCE_FD_OUT | MSM_SUBMIT_SUDO | MSM_SUBMIT_SYNCOBJ_IN | MSM_SUBMIT_SYNCOBJ_OUT | MSM_SUBMIT_FENCE_SN_IN | 0)
#define MSM_SUBMIT_SYNCOBJ_RESET 0x00000001
#define MSM_SUBMIT_SYNCOBJ_FLAGS (MSM_SUBMIT_SYNCOBJ_RESET | 0)
struct drm_msm_gem_submit_syncobj {
@@ -172,6 +181,7 @@
__u32 pad;
};
#define DRM_MSM_GET_PARAM 0x00
+#define DRM_MSM_SET_PARAM 0x01
#define DRM_MSM_GEM_NEW 0x02
#define DRM_MSM_GEM_INFO 0x03
#define DRM_MSM_GEM_CPU_PREP 0x04
@@ -183,6 +193,7 @@
#define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B
#define DRM_MSM_SUBMITQUEUE_QUERY 0x0C
#define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
+#define DRM_IOCTL_MSM_SET_PARAM DRM_IOW(DRM_COMMAND_BASE + DRM_MSM_SET_PARAM, struct drm_msm_param)
#define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
#define DRM_IOCTL_MSM_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_INFO, struct drm_msm_gem_info)
#define DRM_IOCTL_MSM_GEM_CPU_PREP DRM_IOW(DRM_COMMAND_BASE + DRM_MSM_GEM_CPU_PREP, struct drm_msm_gem_cpu_prep)
diff --git a/libc/kernel/uapi/drm/vmwgfx_drm.h b/libc/kernel/uapi/drm/vmwgfx_drm.h
index 395743b..2f75589 100644
--- a/libc/kernel/uapi/drm/vmwgfx_drm.h
+++ b/libc/kernel/uapi/drm/vmwgfx_drm.h
@@ -76,6 +76,7 @@
#define DRM_VMW_PARAM_SM4_1 14
#define DRM_VMW_PARAM_SM5 15
#define DRM_VMW_PARAM_GL43 16
+#define DRM_VMW_PARAM_DEVICE_ID 17
enum drm_vmw_handle_type {
DRM_VMW_HANDLE_LEGACY = 0,
DRM_VMW_HANDLE_PRIME = 1
diff --git a/libc/kernel/uapi/linux/acct.h b/libc/kernel/uapi/linux/acct.h
index aecc9f6..ba9d25f 100644
--- a/libc/kernel/uapi/linux/acct.h
+++ b/libc/kernel/uapi/linux/acct.h
@@ -74,6 +74,7 @@
#define ACOMPAT 0x04
#define ACORE 0x08
#define AXSIG 0x10
+#define AGROUP 0x20
#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
#define ACCT_BYTEORDER 0x80
#elif defined(__BYTE_ORDER)?__BYTE_ORDER==__LITTLE_ENDIAN:defined(__LITTLE_ENDIAN)
diff --git a/libc/kernel/uapi/linux/agpgart.h b/libc/kernel/uapi/linux/agpgart.h
index 3b126f1..9dda7bf 100644
--- a/libc/kernel/uapi/linux/agpgart.h
+++ b/libc/kernel/uapi/linux/agpgart.h
@@ -38,7 +38,6 @@
#define FALSE 0
#endif
#include <linux/types.h>
-#include <stdlib.h>
struct agp_version {
__u16 major;
__u16 minor;
@@ -48,10 +47,10 @@
__u32 bridge_id;
__u32 agp_mode;
unsigned long aper_base;
- size_t aper_size;
- size_t pg_total;
- size_t pg_system;
- size_t pg_used;
+ __kernel_size_t aper_size;
+ __kernel_size_t pg_total;
+ __kernel_size_t pg_system;
+ __kernel_size_t pg_used;
} agp_info;
typedef struct _agp_setup {
__u32 agp_mode;
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index ded1756..e3b3289 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -127,6 +127,11 @@
__u32 sync_recv;
__u32 async_recv;
};
+struct binder_extended_error {
+ __u32 id;
+ __u32 command;
+ __s32 param;
+};
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
@@ -140,12 +145,14 @@
#define BINDER_FREEZE _IOW('b', 14, struct binder_freeze_info)
#define BINDER_GET_FROZEN_INFO _IOWR('b', 15, struct binder_frozen_status_info)
#define BINDER_ENABLE_ONEWAY_SPAM_DETECTION _IOW('b', 16, __u32)
+#define BINDER_GET_EXTENDED_ERROR _IOWR('b', 17, struct binder_extended_error)
enum transaction_flags {
TF_ONE_WAY = 0x01,
TF_ROOT_OBJECT = 0x04,
TF_STATUS_CODE = 0x08,
TF_ACCEPT_FDS = 0x10,
TF_CLEAR_BUF = 0x20,
+ TF_UPDATE_TXN = 0x40,
};
struct binder_transaction_data {
union {
@@ -155,8 +162,8 @@
binder_uintptr_t cookie;
__u32 code;
__u32 flags;
- pid_t sender_pid;
- uid_t sender_euid;
+ __kernel_pid_t sender_pid;
+ __kernel_uid32_t sender_euid;
binder_size_t data_size;
binder_size_t offsets_size;
union {
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index 30a94af..2c37e2a 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -323,6 +323,8 @@
#define AUDIT_ARCH_UNICORE (EM_UNICORE | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_X86_64 (EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_XTENSA (EM_XTENSA)
+#define AUDIT_ARCH_LOONGARCH32 (EM_LOONGARCH | __AUDIT_ARCH_LE)
+#define AUDIT_ARCH_LOONGARCH64 (EM_LOONGARCH | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#define AUDIT_PERM_EXEC 1
#define AUDIT_PERM_WRITE 2
#define AUDIT_PERM_READ 4
diff --git a/libc/kernel/uapi/linux/blkzoned.h b/libc/kernel/uapi/linux/blkzoned.h
index b551e8b..e41ac9f 100644
--- a/libc/kernel/uapi/linux/blkzoned.h
+++ b/libc/kernel/uapi/linux/blkzoned.h
@@ -54,7 +54,7 @@
__u64 sector;
__u32 nr_zones;
__u32 flags;
- struct blk_zone zones[0];
+ struct blk_zone zones[];
};
struct blk_zone_range {
__u64 sector;
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index d363e81..641ac55 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -228,6 +228,8 @@
BPF_SK_REUSEPORT_SELECT,
BPF_SK_REUSEPORT_SELECT_OR_MIGRATE,
BPF_PERF_EVENT,
+ BPF_TRACE_KPROBE_MULTI,
+ BPF_LSM_CGROUP,
__MAX_BPF_ATTACH_TYPE
};
#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
@@ -240,6 +242,8 @@
BPF_LINK_TYPE_NETNS = 5,
BPF_LINK_TYPE_XDP = 6,
BPF_LINK_TYPE_PERF_EVENT = 7,
+ BPF_LINK_TYPE_KPROBE_MULTI = 8,
+ BPF_LINK_TYPE_STRUCT_OPS = 9,
MAX_BPF_LINK_TYPE,
};
#define BPF_F_ALLOW_OVERRIDE (1U << 0)
@@ -250,6 +254,8 @@
#define BPF_F_TEST_RND_HI32 (1U << 2)
#define BPF_F_TEST_STATE_FREQ (1U << 3)
#define BPF_F_SLEEPABLE (1U << 4)
+#define BPF_F_XDP_HAS_FRAGS (1U << 5)
+#define BPF_F_KPROBE_MULTI_RETURN (1U << 0)
#define BPF_PSEUDO_MAP_FD 1
#define BPF_PSEUDO_MAP_IDX 5
#define BPF_PSEUDO_MAP_VALUE 2
@@ -281,6 +287,7 @@
};
#define BPF_F_QUERY_EFFECTIVE (1U << 0)
#define BPF_F_TEST_RUN_ON_CPU (1U << 0)
+#define BPF_F_TEST_XDP_LIVE_FRAMES (1U << 1)
enum bpf_stats_type {
BPF_STATS_RUN_TIME = 0,
};
@@ -392,6 +399,7 @@
__aligned_u64 ctx_out;
__u32 flags;
__u32 cpu;
+ __u32 batch_size;
} test;
struct {
union {
@@ -416,6 +424,7 @@
__u32 attach_flags;
__aligned_u64 prog_ids;
__u32 prog_cnt;
+ __aligned_u64 prog_attach_flags;
} query;
struct {
__u64 name;
@@ -456,6 +465,17 @@
struct {
__u64 bpf_cookie;
} perf_event;
+ struct {
+ __u32 flags;
+ __u32 cnt;
+ __aligned_u64 syms;
+ __aligned_u64 addrs;
+ __aligned_u64 cookies;
+ } kprobe_multi;
+ struct {
+ __u32 target_btf_id;
+ __u64 cookie;
+ } tracing;
};
} link_create;
struct {
@@ -480,7 +500,7 @@
__u32 flags;
} prog_bind_map;
} __attribute__((aligned(8)));
-#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid), FN(set_hash), FN(setsockopt), FN(skb_adjust_room), FN(redirect_map), FN(sk_redirect_map), FN(sock_map_update), FN(xdp_adjust_meta), FN(perf_event_read_value), FN(perf_prog_read_value), FN(getsockopt), FN(override_return), FN(sock_ops_cb_flags_set), FN(msg_redirect_map), FN(msg_apply_bytes), FN(msg_cork_bytes), FN(msg_pull_data), FN(bind), FN(xdp_adjust_tail), FN(skb_get_xfrm_state), FN(get_stack), FN(skb_load_bytes_relative), FN(fib_lookup), FN(sock_hash_update), FN(msg_redirect_hash), FN(sk_redirect_hash), FN(lwt_push_encap), FN(lwt_seg6_store_bytes), FN(lwt_seg6_adjust_srh), FN(lwt_seg6_action), FN(rc_repeat), FN(rc_keydown), FN(skb_cgroup_id), FN(get_current_cgroup_id), FN(get_local_storage), FN(sk_select_reuseport), FN(skb_ancestor_cgroup_id), FN(sk_lookup_tcp), FN(sk_lookup_udp), FN(sk_release), FN(map_push_elem), FN(map_pop_elem), FN(map_peek_elem), FN(msg_push_data), FN(msg_pop_data), FN(rc_pointer_rel), FN(spin_lock), FN(spin_unlock), FN(sk_fullsock), FN(tcp_sock), FN(skb_ecn_set_ce), FN(get_listener_sock), FN(skc_lookup_tcp), FN(tcp_check_syncookie), FN(sysctl_get_name), FN(sysctl_get_current_value), FN(sysctl_get_new_value), FN(sysctl_set_new_value), FN(strtol), FN(strtoul), FN(sk_storage_get), FN(sk_storage_delete), FN(send_signal), FN(tcp_gen_syncookie), FN(skb_output), FN(probe_read_user), FN(probe_read_kernel), FN(probe_read_user_str), FN(probe_read_kernel_str), FN(tcp_send_ack), FN(send_signal_thread), FN(jiffies64), FN(read_branch_records), FN(get_ns_current_pid_tgid), FN(xdp_output), FN(get_netns_cookie), FN(get_current_ancestor_cgroup_id), FN(sk_assign), FN(ktime_get_boot_ns), FN(seq_printf), FN(seq_write), FN(sk_cgroup_id), FN(sk_ancestor_cgroup_id), FN(ringbuf_output), FN(ringbuf_reserve), FN(ringbuf_submit), FN(ringbuf_discard), FN(ringbuf_query), FN(csum_level), FN(skc_to_tcp6_sock), FN(skc_to_tcp_sock), FN(skc_to_tcp_timewait_sock), FN(skc_to_tcp_request_sock), FN(skc_to_udp6_sock), FN(get_task_stack), FN(load_hdr_opt), FN(store_hdr_opt), FN(reserve_hdr_opt), FN(inode_storage_get), FN(inode_storage_delete), FN(d_path), FN(copy_from_user), FN(snprintf_btf), FN(seq_printf_btf), FN(skb_cgroup_classid), FN(redirect_neigh), FN(per_cpu_ptr), FN(this_cpu_ptr), FN(redirect_peer), FN(task_storage_get), FN(task_storage_delete), FN(get_current_task_btf), FN(bprm_opts_set), FN(ktime_get_coarse_ns), FN(ima_inode_hash), FN(sock_from_file), FN(check_mtu), FN(for_each_map_elem), FN(snprintf), FN(sys_bpf), FN(btf_find_by_name_kind), FN(sys_close), FN(timer_init), FN(timer_set_callback), FN(timer_start), FN(timer_cancel), FN(get_func_ip), FN(get_attach_cookie), FN(task_pt_regs), FN(get_branch_snapshot), FN(trace_vprintk), FN(skc_to_unix_sock), FN(kallsyms_lookup_name), FN(find_vma), FN(loop), FN(strncmp), FN(get_func_arg), FN(get_func_ret), FN(get_func_arg_cnt),
+#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid), FN(set_hash), FN(setsockopt), FN(skb_adjust_room), FN(redirect_map), FN(sk_redirect_map), FN(sock_map_update), FN(xdp_adjust_meta), FN(perf_event_read_value), FN(perf_prog_read_value), FN(getsockopt), FN(override_return), FN(sock_ops_cb_flags_set), FN(msg_redirect_map), FN(msg_apply_bytes), FN(msg_cork_bytes), FN(msg_pull_data), FN(bind), FN(xdp_adjust_tail), FN(skb_get_xfrm_state), FN(get_stack), FN(skb_load_bytes_relative), FN(fib_lookup), FN(sock_hash_update), FN(msg_redirect_hash), FN(sk_redirect_hash), FN(lwt_push_encap), FN(lwt_seg6_store_bytes), FN(lwt_seg6_adjust_srh), FN(lwt_seg6_action), FN(rc_repeat), FN(rc_keydown), FN(skb_cgroup_id), FN(get_current_cgroup_id), FN(get_local_storage), FN(sk_select_reuseport), FN(skb_ancestor_cgroup_id), FN(sk_lookup_tcp), FN(sk_lookup_udp), FN(sk_release), FN(map_push_elem), FN(map_pop_elem), FN(map_peek_elem), FN(msg_push_data), FN(msg_pop_data), FN(rc_pointer_rel), FN(spin_lock), FN(spin_unlock), FN(sk_fullsock), FN(tcp_sock), FN(skb_ecn_set_ce), FN(get_listener_sock), FN(skc_lookup_tcp), FN(tcp_check_syncookie), FN(sysctl_get_name), FN(sysctl_get_current_value), FN(sysctl_get_new_value), FN(sysctl_set_new_value), FN(strtol), FN(strtoul), FN(sk_storage_get), FN(sk_storage_delete), FN(send_signal), FN(tcp_gen_syncookie), FN(skb_output), FN(probe_read_user), FN(probe_read_kernel), FN(probe_read_user_str), FN(probe_read_kernel_str), FN(tcp_send_ack), FN(send_signal_thread), FN(jiffies64), FN(read_branch_records), FN(get_ns_current_pid_tgid), FN(xdp_output), FN(get_netns_cookie), FN(get_current_ancestor_cgroup_id), FN(sk_assign), FN(ktime_get_boot_ns), FN(seq_printf), FN(seq_write), FN(sk_cgroup_id), FN(sk_ancestor_cgroup_id), FN(ringbuf_output), FN(ringbuf_reserve), FN(ringbuf_submit), FN(ringbuf_discard), FN(ringbuf_query), FN(csum_level), FN(skc_to_tcp6_sock), FN(skc_to_tcp_sock), FN(skc_to_tcp_timewait_sock), FN(skc_to_tcp_request_sock), FN(skc_to_udp6_sock), FN(get_task_stack), FN(load_hdr_opt), FN(store_hdr_opt), FN(reserve_hdr_opt), FN(inode_storage_get), FN(inode_storage_delete), FN(d_path), FN(copy_from_user), FN(snprintf_btf), FN(seq_printf_btf), FN(skb_cgroup_classid), FN(redirect_neigh), FN(per_cpu_ptr), FN(this_cpu_ptr), FN(redirect_peer), FN(task_storage_get), FN(task_storage_delete), FN(get_current_task_btf), FN(bprm_opts_set), FN(ktime_get_coarse_ns), FN(ima_inode_hash), FN(sock_from_file), FN(check_mtu), FN(for_each_map_elem), FN(snprintf), FN(sys_bpf), FN(btf_find_by_name_kind), FN(sys_close), FN(timer_init), FN(timer_set_callback), FN(timer_start), FN(timer_cancel), FN(get_func_ip), FN(get_attach_cookie), FN(task_pt_regs), FN(get_branch_snapshot), FN(trace_vprintk), FN(skc_to_unix_sock), FN(kallsyms_lookup_name), FN(find_vma), FN(loop), FN(strncmp), FN(get_func_arg), FN(get_func_ret), FN(get_func_arg_cnt), FN(get_retval), FN(set_retval), FN(xdp_get_buff_len), FN(xdp_load_bytes), FN(xdp_store_bytes), FN(copy_from_user_task), FN(skb_set_tstamp), FN(ima_file_hash), FN(kptr_xchg), FN(map_lookup_percpu_elem), FN(skc_to_mptcp_sock), FN(dynptr_from_mem), FN(ringbuf_reserve_dynptr), FN(ringbuf_submit_dynptr), FN(ringbuf_discard_dynptr), FN(dynptr_read), FN(dynptr_write), FN(dynptr_data), FN(tcp_raw_gen_syncookie_ipv4), FN(tcp_raw_gen_syncookie_ipv6), FN(tcp_raw_check_syncookie_ipv4), FN(tcp_raw_check_syncookie_ipv6),
#define __BPF_ENUM_FN(x) BPF_FUNC_ ##x
enum bpf_func_id {
__BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
@@ -595,6 +615,10 @@
};
#define __bpf_md_ptr(type,name) union { type name; __u64 : 64; \
} __attribute__((aligned(8)))
+enum {
+ BPF_SKB_TSTAMP_UNSPEC,
+ BPF_SKB_TSTAMP_DELIVERY_MONO,
+};
struct __sk_buff {
__u32 len;
__u32 pkt_type;
@@ -628,7 +652,8 @@
__u32 gso_segs;
__bpf_md_ptr(struct bpf_sock *, sk);
__u32 gso_size;
- __u32 : 32;
+ __u8 tstamp_type;
+ __u32 : 24;
__u64 hwtstamp;
};
struct bpf_tunnel_key {
@@ -641,6 +666,10 @@
__u8 tunnel_ttl;
__u16 tunnel_ext;
__u32 tunnel_label;
+ union {
+ __u32 local_ipv4;
+ __u32 local_ipv6[4];
+ };
};
struct bpf_xfrm_state {
__u32 reqid;
@@ -668,7 +697,8 @@
__u32 src_ip4;
__u32 src_ip6[4];
__u32 src_port;
- __u32 dst_port;
+ __be16 dst_port;
+ __u16 : 16;
__u32 dst_ip4;
__u32 dst_ip6[4];
__u32 state;
@@ -818,6 +848,8 @@
__u64 run_cnt;
__u64 recursion_misses;
__u32 verified_insns;
+ __u32 attach_btf_obj_id;
+ __u32 attach_btf_id;
} __attribute__((aligned(8)));
struct bpf_map_info {
__u32 type;
@@ -1134,6 +1166,10 @@
__u64 : 64;
__u64 : 64;
} __attribute__((aligned(8)));
+struct bpf_dynptr {
+ __u64 : 64;
+ __u64 : 64;
+} __attribute__((aligned(8)));
struct bpf_sysctl {
__u32 write;
__u32 file_pos;
@@ -1160,7 +1196,8 @@
__u32 protocol;
__u32 remote_ip4;
__u32 remote_ip6[4];
- __u32 remote_port;
+ __be16 remote_port;
+ __u16 : 16;
__u32 local_ip4;
__u32 local_ip6[4];
__u32 local_port;
@@ -1190,6 +1227,7 @@
BPF_CORE_TYPE_SIZE = 9,
BPF_CORE_ENUMVAL_EXISTS = 10,
BPF_CORE_ENUMVAL_VALUE = 11,
+ BPF_CORE_TYPE_MATCHES = 12,
};
struct bpf_core_relo {
__u32 insn_off;
diff --git a/libc/kernel/uapi/linux/btf.h b/libc/kernel/uapi/linux/btf.h
index fc57d3c..a1f68bf 100644
--- a/libc/kernel/uapi/linux/btf.h
+++ b/libc/kernel/uapi/linux/btf.h
@@ -65,6 +65,7 @@
BTF_KIND_FLOAT = 16,
BTF_KIND_DECL_TAG = 17,
BTF_KIND_TYPE_TAG = 18,
+ BTF_KIND_ENUM64 = 19,
NR_BTF_KINDS,
BTF_KIND_MAX = NR_BTF_KINDS - 1,
};
@@ -115,4 +116,9 @@
struct btf_decl_tag {
__s32 component_idx;
};
+struct btf_enum64 {
+ __u32 name_off;
+ __u32 val_lo32;
+ __u32 val_hi32;
+};
#endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 08b96a3..d73527e 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -59,7 +59,7 @@
__u64 num_ref_copies;
__u64 num_excl_copies;
struct btrfs_qgroup_limit lim;
- __u64 qgroups[0];
+ __u64 qgroups[];
};
struct btrfs_ioctl_qgroup_limit_args {
__u64 qgroupid;
@@ -189,6 +189,7 @@
#define BTRFS_FEATURE_INCOMPAT_METADATA_UUID (1ULL << 10)
#define BTRFS_FEATURE_INCOMPAT_RAID1C34 (1ULL << 11)
#define BTRFS_FEATURE_INCOMPAT_ZONED (1ULL << 12)
+#define BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2 (1ULL << 13)
struct btrfs_ioctl_feature_flags {
__u64 compat_flags;
__u64 compat_ro_flags;
@@ -303,7 +304,7 @@
struct btrfs_ioctl_search_args_v2 {
struct btrfs_ioctl_search_key key;
__u64 buf_size;
- __u64 buf[0];
+ __u64 buf[];
};
struct btrfs_ioctl_clone_range_args {
__s64 src_fd;
@@ -334,7 +335,7 @@
__u16 dest_count;
__u16 reserved1;
__u32 reserved2;
- struct btrfs_ioctl_same_extent_info info[0];
+ struct btrfs_ioctl_same_extent_info info[];
};
struct btrfs_ioctl_space_info {
__u64 flags;
@@ -344,14 +345,14 @@
struct btrfs_ioctl_space_args {
__u64 space_slots;
__u64 total_spaces;
- struct btrfs_ioctl_space_info spaces[0];
+ struct btrfs_ioctl_space_info spaces[];
};
struct btrfs_data_container {
__u32 bytes_left;
__u32 bytes_missing;
__u32 elem_cnt;
__u32 elem_missed;
- __u64 val[0];
+ __u64 val[];
};
struct btrfs_ioctl_ino_path_args {
__u64 inum;
@@ -421,7 +422,8 @@
#define BTRFS_SEND_FLAG_OMIT_STREAM_HEADER 0x2
#define BTRFS_SEND_FLAG_OMIT_END_CMD 0x4
#define BTRFS_SEND_FLAG_VERSION 0x8
-#define BTRFS_SEND_FLAG_MASK (BTRFS_SEND_FLAG_NO_FILE_DATA | BTRFS_SEND_FLAG_OMIT_STREAM_HEADER | BTRFS_SEND_FLAG_OMIT_END_CMD | BTRFS_SEND_FLAG_VERSION)
+#define BTRFS_SEND_FLAG_COMPRESSED 0x10
+#define BTRFS_SEND_FLAG_MASK (BTRFS_SEND_FLAG_NO_FILE_DATA | BTRFS_SEND_FLAG_OMIT_STREAM_HEADER | BTRFS_SEND_FLAG_OMIT_END_CMD | BTRFS_SEND_FLAG_VERSION | BTRFS_SEND_FLAG_COMPRESSED)
struct btrfs_ioctl_send_args {
__s64 send_fd;
__u64 clone_sources_count;
@@ -461,6 +463,29 @@
__u8 num_items;
__u8 align[7];
};
+struct btrfs_ioctl_encoded_io_args {
+ const struct iovec __user * iov;
+ unsigned long iovcnt;
+ __s64 offset;
+ __u64 flags;
+ __u64 len;
+ __u64 unencoded_len;
+ __u64 unencoded_offset;
+ __u32 compression;
+ __u32 encryption;
+ __u8 reserved[64];
+};
+#define BTRFS_ENCODED_IO_COMPRESSION_NONE 0
+#define BTRFS_ENCODED_IO_COMPRESSION_ZLIB 1
+#define BTRFS_ENCODED_IO_COMPRESSION_ZSTD 2
+#define BTRFS_ENCODED_IO_COMPRESSION_LZO_4K 3
+#define BTRFS_ENCODED_IO_COMPRESSION_LZO_8K 4
+#define BTRFS_ENCODED_IO_COMPRESSION_LZO_16K 5
+#define BTRFS_ENCODED_IO_COMPRESSION_LZO_32K 6
+#define BTRFS_ENCODED_IO_COMPRESSION_LZO_64K 7
+#define BTRFS_ENCODED_IO_COMPRESSION_TYPES 8
+#define BTRFS_ENCODED_IO_ENCRYPTION_NONE 0
+#define BTRFS_ENCODED_IO_ENCRYPTION_TYPES 1
enum btrfs_err_code {
BTRFS_ERROR_DEV_RAID1_MIN_NOT_MET = 1,
BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET,
@@ -534,4 +559,6 @@
#define BTRFS_IOC_GET_SUBVOL_ROOTREF _IOWR(BTRFS_IOCTL_MAGIC, 61, struct btrfs_ioctl_get_subvol_rootref_args)
#define BTRFS_IOC_INO_LOOKUP_USER _IOWR(BTRFS_IOCTL_MAGIC, 62, struct btrfs_ioctl_ino_lookup_user_args)
#define BTRFS_IOC_SNAP_DESTROY_V2 _IOW(BTRFS_IOCTL_MAGIC, 63, struct btrfs_ioctl_vol_args_v2)
+#define BTRFS_IOC_ENCODED_READ _IOR(BTRFS_IOCTL_MAGIC, 64, struct btrfs_ioctl_encoded_io_args)
+#define BTRFS_IOC_ENCODED_WRITE _IOW(BTRFS_IOCTL_MAGIC, 64, struct btrfs_ioctl_encoded_io_args)
#endif
diff --git a/libc/kernel/uapi/linux/btrfs_tree.h b/libc/kernel/uapi/linux/btrfs_tree.h
index 0476733..3becce8 100644
--- a/libc/kernel/uapi/linux/btrfs_tree.h
+++ b/libc/kernel/uapi/linux/btrfs_tree.h
@@ -31,6 +31,7 @@
#define BTRFS_QUOTA_TREE_OBJECTID 8ULL
#define BTRFS_UUID_TREE_OBJECTID 9ULL
#define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
+#define BTRFS_BLOCK_GROUP_TREE_OBJECTID 11ULL
#define BTRFS_DEV_STATS_OBJECTID 0ULL
#define BTRFS_BALANCE_OBJECTID - 4ULL
#define BTRFS_ORPHAN_OBJECTID - 5ULL
@@ -220,7 +221,7 @@
__le64 parent_objectid;
__le64 index;
__le16 name_len;
- __u8 name[0];
+ __u8 name[];
} __attribute__((__packed__));
struct btrfs_timespec {
__le64 sec;
@@ -372,18 +373,6 @@
#define BTRFS_BLOCK_GROUP_RAID1C3 (1ULL << 9)
#define BTRFS_BLOCK_GROUP_RAID1C4 (1ULL << 10)
#define BTRFS_BLOCK_GROUP_RESERVED (BTRFS_AVAIL_ALLOC_BIT_SINGLE | BTRFS_SPACE_INFO_GLOBAL_RSV)
-enum btrfs_raid_types {
- BTRFS_RAID_RAID10,
- BTRFS_RAID_RAID1,
- BTRFS_RAID_DUP,
- BTRFS_RAID_RAID0,
- BTRFS_RAID_SINGLE,
- BTRFS_RAID_RAID5,
- BTRFS_RAID_RAID6,
- BTRFS_RAID_RAID1C3,
- BTRFS_RAID_RAID1C4,
- BTRFS_NR_RAID_TYPES
-};
#define BTRFS_BLOCK_GROUP_TYPE_MASK (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_SYSTEM | BTRFS_BLOCK_GROUP_METADATA)
#define BTRFS_BLOCK_GROUP_PROFILE_MASK (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID1C3 | BTRFS_BLOCK_GROUP_RAID1C4 | BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6 | BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID10)
#define BTRFS_BLOCK_GROUP_RAID56_MASK (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6)
diff --git a/libc/kernel/uapi/linux/cachefiles.h b/libc/kernel/uapi/linux/cachefiles.h
new file mode 100644
index 0000000..f5a58a5
--- /dev/null
+++ b/libc/kernel/uapi/linux/cachefiles.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_CACHEFILES_H
+#define _LINUX_CACHEFILES_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define CACHEFILES_MSG_MAX_SIZE 1024
+enum cachefiles_opcode {
+ CACHEFILES_OP_OPEN,
+ CACHEFILES_OP_CLOSE,
+ CACHEFILES_OP_READ,
+};
+struct cachefiles_msg {
+ __u32 msg_id;
+ __u32 opcode;
+ __u32 len;
+ __u32 object_id;
+ __u8 data[];
+};
+struct cachefiles_open {
+ __u32 volume_key_size;
+ __u32 cookie_key_size;
+ __u32 fd;
+ __u32 flags;
+ __u8 data[];
+};
+struct cachefiles_read {
+ __u64 off;
+ __u64 len;
+};
+#define CACHEFILES_IOC_READ_COMPLETE _IOW(0x98, 1, int)
+#endif
diff --git a/libc/kernel/uapi/linux/can/bcm.h b/libc/kernel/uapi/linux/can/bcm.h
index 42e0782..f5ab2c2 100644
--- a/libc/kernel/uapi/linux/can/bcm.h
+++ b/libc/kernel/uapi/linux/can/bcm.h
@@ -31,7 +31,7 @@
struct bcm_timeval ival1, ival2;
canid_t can_id;
__u32 nframes;
- struct can_frame frames[0];
+ struct can_frame frames[];
};
enum {
TX_SETUP = 1,
diff --git a/libc/kernel/uapi/linux/can/error.h b/libc/kernel/uapi/linux/can/error.h
index 645373b..f585d2c 100644
--- a/libc/kernel/uapi/linux/can/error.h
+++ b/libc/kernel/uapi/linux/can/error.h
@@ -28,6 +28,7 @@
#define CAN_ERR_BUSOFF 0x00000040U
#define CAN_ERR_BUSERROR 0x00000080U
#define CAN_ERR_RESTARTED 0x00000100U
+#define CAN_ERR_CNT 0x00000200U
#define CAN_ERR_LOSTARB_UNSPEC 0x00
#define CAN_ERR_CRTL_UNSPEC 0x00
#define CAN_ERR_CRTL_RX_OVERFLOW 0x01
@@ -76,4 +77,7 @@
#define CAN_ERR_TRX_CANL_SHORT_TO_VCC 0x60
#define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70
#define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80
+#define CAN_ERROR_WARNING_THRESHOLD 96
+#define CAN_ERROR_PASSIVE_THRESHOLD 128
+#define CAN_BUS_OFF_THRESHOLD 256
#endif
diff --git a/libc/kernel/uapi/linux/can/isotp.h b/libc/kernel/uapi/linux/can/isotp.h
index dd5e4f5..f51aa59 100644
--- a/libc/kernel/uapi/linux/can/isotp.h
+++ b/libc/kernel/uapi/linux/can/isotp.h
@@ -44,26 +44,28 @@
__u8 tx_dl;
__u8 tx_flags;
};
-#define CAN_ISOTP_LISTEN_MODE 0x001
-#define CAN_ISOTP_EXTEND_ADDR 0x002
-#define CAN_ISOTP_TX_PADDING 0x004
-#define CAN_ISOTP_RX_PADDING 0x008
-#define CAN_ISOTP_CHK_PAD_LEN 0x010
-#define CAN_ISOTP_CHK_PAD_DATA 0x020
-#define CAN_ISOTP_HALF_DUPLEX 0x040
-#define CAN_ISOTP_FORCE_TXSTMIN 0x080
-#define CAN_ISOTP_FORCE_RXSTMIN 0x100
-#define CAN_ISOTP_RX_EXT_ADDR 0x200
-#define CAN_ISOTP_WAIT_TX_DONE 0x400
-#define CAN_ISOTP_SF_BROADCAST 0x800
+#define CAN_ISOTP_LISTEN_MODE 0x0001
+#define CAN_ISOTP_EXTEND_ADDR 0x0002
+#define CAN_ISOTP_TX_PADDING 0x0004
+#define CAN_ISOTP_RX_PADDING 0x0008
+#define CAN_ISOTP_CHK_PAD_LEN 0x0010
+#define CAN_ISOTP_CHK_PAD_DATA 0x0020
+#define CAN_ISOTP_HALF_DUPLEX 0x0040
+#define CAN_ISOTP_FORCE_TXSTMIN 0x0080
+#define CAN_ISOTP_FORCE_RXSTMIN 0x0100
+#define CAN_ISOTP_RX_EXT_ADDR 0x0200
+#define CAN_ISOTP_WAIT_TX_DONE 0x0400
+#define CAN_ISOTP_SF_BROADCAST 0x0800
+#define CAN_ISOTP_CF_BROADCAST 0x1000
#define CAN_ISOTP_DEFAULT_FLAGS 0
#define CAN_ISOTP_DEFAULT_EXT_ADDRESS 0x00
#define CAN_ISOTP_DEFAULT_PAD_CONTENT 0xCC
-#define CAN_ISOTP_DEFAULT_FRAME_TXTIME 0
+#define CAN_ISOTP_DEFAULT_FRAME_TXTIME 50000
#define CAN_ISOTP_DEFAULT_RECV_BS 0
#define CAN_ISOTP_DEFAULT_RECV_STMIN 0x00
#define CAN_ISOTP_DEFAULT_RECV_WFTMAX 0
#define CAN_ISOTP_DEFAULT_LL_MTU CAN_MTU
#define CAN_ISOTP_DEFAULT_LL_TX_DL CAN_MAX_DLEN
#define CAN_ISOTP_DEFAULT_LL_TX_FLAGS 0
+#define CAN_ISOTP_FRAME_TXTIME_ZERO 0xFFFFFFFF
#endif
diff --git a/libc/kernel/uapi/linux/connector.h b/libc/kernel/uapi/linux/connector.h
index adf3a7f..e3891e3 100644
--- a/libc/kernel/uapi/linux/connector.h
+++ b/libc/kernel/uapi/linux/connector.h
@@ -50,6 +50,6 @@
__u32 ack;
__u16 len;
__u16 flags;
- __u8 data[0];
+ __u8 data[];
};
#endif
diff --git a/libc/kernel/uapi/linux/counter.h b/libc/kernel/uapi/linux/counter.h
index 091e33d..4b86b28 100644
--- a/libc/kernel/uapi/linux/counter.h
+++ b/libc/kernel/uapi/linux/counter.h
@@ -45,6 +45,7 @@
COUNTER_EVENT_OVERFLOW_UNDERFLOW,
COUNTER_EVENT_THRESHOLD,
COUNTER_EVENT_INDEX,
+ COUNTER_EVENT_CHANGE_OF_STATE,
};
struct counter_watch {
struct counter_component component;
diff --git a/libc/kernel/uapi/linux/cxl_mem.h b/libc/kernel/uapi/linux/cxl_mem.h
index 15e9e29..578cefd 100644
--- a/libc/kernel/uapi/linux/cxl_mem.h
+++ b/libc/kernel/uapi/linux/cxl_mem.h
@@ -38,8 +38,8 @@
__u32 id;
__u32 flags;
#define CXL_MEM_COMMAND_FLAG_MASK GENMASK(0, 0)
- __s32 size_in;
- __s32 size_out;
+ __u32 size_in;
+ __u32 size_out;
};
struct cxl_mem_query_commands {
__u32 n_commands;
@@ -58,12 +58,12 @@
};
__u32 retval;
struct {
- __s32 size;
+ __u32 size;
__u32 rsvd;
__u64 payload;
} in;
struct {
- __s32 size;
+ __u32 size;
__u32 rsvd;
__u64 payload;
} out;
diff --git a/libc/kernel/uapi/linux/cycx_cfm.h b/libc/kernel/uapi/linux/cycx_cfm.h
index 052de53..230b58d 100644
--- a/libc/kernel/uapi/linux/cycx_cfm.h
+++ b/libc/kernel/uapi/linux/cycx_cfm.h
@@ -53,7 +53,7 @@
unsigned short reserved[6];
char descr[CFM_DESCR_LEN];
struct cycx_fw_info info;
- unsigned char image[0];
+ unsigned char image[];
};
struct cycx_fw_header {
unsigned long reset_size;
diff --git a/libc/kernel/uapi/linux/devlink.h b/libc/kernel/uapi/linux/devlink.h
index a809306..b2cdafa 100644
--- a/libc/kernel/uapi/linux/devlink.h
+++ b/libc/kernel/uapi/linux/devlink.h
@@ -103,6 +103,12 @@
DEVLINK_CMD_RATE_SET,
DEVLINK_CMD_RATE_NEW,
DEVLINK_CMD_RATE_DEL,
+ DEVLINK_CMD_LINECARD_GET,
+ DEVLINK_CMD_LINECARD_SET,
+ DEVLINK_CMD_LINECARD_NEW,
+ DEVLINK_CMD_LINECARD_DEL,
+ DEVLINK_CMD_SELFTESTS_GET,
+ DEVLINK_CMD_SELFTESTS_RUN,
__DEVLINK_CMD_MAX,
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
};
@@ -184,6 +190,25 @@
#define DEVLINK_FLASH_OVERWRITE_SETTINGS _BITUL(DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT)
#define DEVLINK_FLASH_OVERWRITE_IDENTIFIERS _BITUL(DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT)
#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS (_BITUL(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)
+enum devlink_attr_selftest_id {
+ DEVLINK_ATTR_SELFTEST_ID_UNSPEC,
+ DEVLINK_ATTR_SELFTEST_ID_FLASH,
+ __DEVLINK_ATTR_SELFTEST_ID_MAX,
+ DEVLINK_ATTR_SELFTEST_ID_MAX = __DEVLINK_ATTR_SELFTEST_ID_MAX - 1
+};
+enum devlink_selftest_status {
+ DEVLINK_SELFTEST_STATUS_SKIP,
+ DEVLINK_SELFTEST_STATUS_PASS,
+ DEVLINK_SELFTEST_STATUS_FAIL
+};
+enum devlink_attr_selftest_result {
+ DEVLINK_ATTR_SELFTEST_RESULT_UNSPEC,
+ DEVLINK_ATTR_SELFTEST_RESULT,
+ DEVLINK_ATTR_SELFTEST_RESULT_ID,
+ DEVLINK_ATTR_SELFTEST_RESULT_STATUS,
+ __DEVLINK_ATTR_SELFTEST_RESULT_MAX,
+ DEVLINK_ATTR_SELFTEST_RESULT_MAX = __DEVLINK_ATTR_SELFTEST_RESULT_MAX - 1
+};
enum devlink_trap_action {
DEVLINK_TRAP_ACTION_DROP,
DEVLINK_TRAP_ACTION_TRAP,
@@ -212,6 +237,17 @@
DEVLINK_RELOAD_LIMIT_MAX = __DEVLINK_RELOAD_LIMIT_MAX - 1
};
#define DEVLINK_RELOAD_LIMITS_VALID_MASK (_BITUL(__DEVLINK_RELOAD_LIMIT_MAX) - 1)
+enum devlink_linecard_state {
+ DEVLINK_LINECARD_STATE_UNSPEC,
+ DEVLINK_LINECARD_STATE_UNPROVISIONED,
+ DEVLINK_LINECARD_STATE_UNPROVISIONING,
+ DEVLINK_LINECARD_STATE_PROVISIONING,
+ DEVLINK_LINECARD_STATE_PROVISIONING_FAILED,
+ DEVLINK_LINECARD_STATE_PROVISIONED,
+ DEVLINK_LINECARD_STATE_ACTIVE,
+ __DEVLINK_LINECARD_STATE_MAX,
+ DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1
+};
enum devlink_attr {
DEVLINK_ATTR_UNSPEC,
DEVLINK_ATTR_BUS_NAME,
@@ -384,6 +420,12 @@
DEVLINK_ATTR_RATE_NODE_NAME,
DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
+ DEVLINK_ATTR_LINECARD_INDEX,
+ DEVLINK_ATTR_LINECARD_STATE,
+ DEVLINK_ATTR_LINECARD_TYPE,
+ DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES,
+ DEVLINK_ATTR_NESTED_DEVLINK,
+ DEVLINK_ATTR_SELFTESTS,
__DEVLINK_ATTR_MAX,
DEVLINK_ATTR_MAX = __DEVLINK_ATTR_MAX - 1
};
diff --git a/libc/kernel/uapi/linux/dm-ioctl.h b/libc/kernel/uapi/linux/dm-ioctl.h
index 09f8a98..f0ff78c 100644
--- a/libc/kernel/uapi/linux/dm-ioctl.h
+++ b/libc/kernel/uapi/linux/dm-ioctl.h
@@ -48,23 +48,23 @@
struct dm_target_deps {
__u32 count;
__u32 padding;
- __u64 dev[0];
+ __u64 dev[];
};
struct dm_name_list {
__u64 dev;
__u32 next;
- char name[0];
+ char name[];
};
#define DM_NAME_LIST_FLAG_HAS_UUID 1
#define DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID 2
struct dm_target_versions {
__u32 next;
__u32 version[3];
- char name[0];
+ char name[];
};
struct dm_target_msg {
__u64 sector;
- char message[0];
+ char message[];
};
enum {
DM_VERSION_CMD = 0,
@@ -106,9 +106,9 @@
#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 45
+#define DM_VERSION_MINOR 47
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl(2021-03-22)"
+#define DM_VERSION_EXTRA "-ioctl(2022-07-28)"
#define DM_READONLY_FLAG (1 << 0)
#define DM_SUSPEND_FLAG (1 << 1)
#define DM_PERSISTENT_DEV_FLAG (1 << 3)
diff --git a/libc/kernel/uapi/linux/dm-log-userspace.h b/libc/kernel/uapi/linux/dm-log-userspace.h
index 4f0671b..37feee6 100644
--- a/libc/kernel/uapi/linux/dm-log-userspace.h
+++ b/libc/kernel/uapi/linux/dm-log-userspace.h
@@ -49,6 +49,6 @@
__u32 seq;
__u32 request_type;
__u32 data_size;
- char data[0];
+ char data[];
};
#endif
diff --git a/libc/kernel/uapi/linux/dma-buf.h b/libc/kernel/uapi/linux/dma-buf.h
index 221c20f..7462c15 100644
--- a/libc/kernel/uapi/linux/dma-buf.h
+++ b/libc/kernel/uapi/linux/dma-buf.h
@@ -29,9 +29,19 @@
#define DMA_BUF_SYNC_END (1 << 2)
#define DMA_BUF_SYNC_VALID_FLAGS_MASK (DMA_BUF_SYNC_RW | DMA_BUF_SYNC_END)
#define DMA_BUF_NAME_LEN 32
+struct dma_buf_export_sync_file {
+ __u32 flags;
+ __s32 fd;
+};
+struct dma_buf_import_sync_file {
+ __u32 flags;
+ __s32 fd;
+};
#define DMA_BUF_BASE 'b'
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
#define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *)
-#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32)
-#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64)
+#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, __u32)
+#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, __u64)
+#define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file)
+#define DMA_BUF_IOCTL_IMPORT_SYNC_FILE _IOW(DMA_BUF_BASE, 3, struct dma_buf_import_sync_file)
#endif
diff --git a/libc/kernel/uapi/linux/elf-em.h b/libc/kernel/uapi/linux/elf-em.h
index d1ed1f6..92da93d 100644
--- a/libc/kernel/uapi/linux/elf-em.h
+++ b/libc/kernel/uapi/linux/elf-em.h
@@ -61,6 +61,7 @@
#define EM_RISCV 243
#define EM_BPF 247
#define EM_CSKY 252
+#define EM_LOONGARCH 258
#define EM_FRV 0x5441
#define EM_ALPHA 0x9026
#define EM_CYGNUS_M32R 0x9041
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index 7655f12..28c8426 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -45,9 +45,11 @@
#define PT_HIOS 0x6fffffff
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff
-#define PT_GNU_EH_FRAME 0x6474e550
-#define PT_GNU_PROPERTY 0x6474e553
+#define PT_GNU_EH_FRAME (PT_LOOS + 0x474e550)
#define PT_GNU_STACK (PT_LOOS + 0x474e551)
+#define PT_GNU_RELRO (PT_LOOS + 0x474e552)
+#define PT_GNU_PROPERTY (PT_LOOS + 0x474e553)
+#define PT_AARCH64_MEMTAG_MTE (PT_LOPROC + 0x2)
#define PN_XNUM 0xffff
#define ET_NONE 0
#define ET_REL 1
@@ -110,7 +112,7 @@
#define STT_COMMON 5
#define STT_TLS 6
#define ELF_ST_BIND(x) ((x) >> 4)
-#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
+#define ELF_ST_TYPE(x) ((x) & 0xf)
#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
@@ -350,6 +352,7 @@
#define NT_S390_GS_CB 0x30b
#define NT_S390_GS_BC 0x30c
#define NT_S390_RI_CB 0x30d
+#define NT_S390_PV_CPU_DATA 0x30e
#define NT_ARM_VFP 0x400
#define NT_ARM_TLS 0x401
#define NT_ARM_HW_BREAK 0x402
@@ -361,11 +364,18 @@
#define NT_ARM_PACG_KEYS 0x408
#define NT_ARM_TAGGED_ADDR_CTRL 0x409
#define NT_ARM_PAC_ENABLED_KEYS 0x40a
+#define NT_ARM_SSVE 0x40b
+#define NT_ARM_ZA 0x40c
#define NT_ARC_V2 0x600
#define NT_VMCOREDD 0x700
#define NT_MIPS_DSP 0x800
#define NT_MIPS_FP_MODE 0x801
#define NT_MIPS_MSA 0x802
+#define NT_LOONGARCH_CPUCFG 0xa00
+#define NT_LOONGARCH_CSR 0xa01
+#define NT_LOONGARCH_LSX 0xa02
+#define NT_LOONGARCH_LASX 0xa03
+#define NT_LOONGARCH_LBT 0xa04
#define NT_GNU_PROPERTY_TYPE_0 5
typedef struct elf32_note {
Elf32_Word n_namesz;
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index 741ea2a..22dc9f2 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -98,7 +98,7 @@
__u32 id;
__u32 type_id;
__u32 len;
- void * data[0];
+ void * data[];
};
#define DOWNSHIFT_DEV_DEFAULT_COUNT 0xff
#define DOWNSHIFT_DEV_DISABLE 0
@@ -118,14 +118,14 @@
__u32 cmd;
__u32 version;
__u32 len;
- __u8 data[0];
+ __u8 data[];
};
struct ethtool_eeprom {
__u32 cmd;
__u32 magic;
__u32 offset;
__u32 len;
- __u8 data[0];
+ __u8 data[];
};
struct ethtool_eee {
__u32 cmd;
@@ -281,13 +281,13 @@
__u32 cmd;
__u32 string_set;
__u32 len;
- __u8 data[0];
+ __u8 data[];
};
struct ethtool_sset_info {
__u32 cmd;
__u32 reserved;
__u64 sset_mask;
- __u32 data[0];
+ __u32 data[];
};
enum ethtool_test_flags {
ETH_TEST_FL_OFFLINE = (1 << 0),
@@ -300,17 +300,17 @@
__u32 flags;
__u32 reserved;
__u32 len;
- __u64 data[0];
+ __u64 data[];
};
struct ethtool_stats {
__u32 cmd;
__u32 n_stats;
- __u64 data[0];
+ __u64 data[];
};
struct ethtool_perm_addr {
__u32 cmd;
__u32 size;
- __u8 data[0];
+ __u8 data[];
};
enum ethtool_flags {
ETH_FLAG_TXVLAN = (1 << 7),
@@ -410,7 +410,7 @@
struct ethtool_rxfh_indir {
__u32 cmd;
__u32 size;
- __u32 ring_index[0];
+ __u32 ring_index[];
};
struct ethtool_rxfh {
__u32 cmd;
@@ -420,7 +420,7 @@
__u8 hfunc;
__u8 rsvd8[3];
__u32 rsvd32;
- __u32 rss_config[0];
+ __u32 rss_config[];
};
#define ETH_RXFH_CONTEXT_ALLOC 0xffffffff
#define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff
@@ -462,7 +462,7 @@
__u32 version;
__u32 flag;
__u32 len;
- __u8 data[0];
+ __u8 data[];
};
#define ETH_FW_DUMP_DISABLE 0
struct ethtool_get_features_block {
@@ -474,7 +474,7 @@
struct ethtool_gfeatures {
__u32 cmd;
__u32 size;
- struct ethtool_get_features_block features[0];
+ struct ethtool_get_features_block features[];
};
struct ethtool_set_features_block {
__u32 valid;
@@ -483,7 +483,7 @@
struct ethtool_sfeatures {
__u32 cmd;
__u32 size;
- struct ethtool_set_features_block features[0];
+ struct ethtool_set_features_block features[];
};
struct ethtool_ts_info {
__u32 cmd;
@@ -704,6 +704,7 @@
ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT = 89,
ETHTOOL_LINK_MODE_100baseFX_Half_BIT = 90,
ETHTOOL_LINK_MODE_100baseFX_Full_BIT = 91,
+ ETHTOOL_LINK_MODE_10baseT1L_Full_BIT = 92,
__ETHTOOL_LINK_MODE_MASK_NBITS
};
#define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) (1UL << (ETHTOOL_LINK_MODE_ ##base_name ##_BIT))
@@ -902,6 +903,6 @@
__u8 master_slave_state;
__u8 reserved1[1];
__u32 reserved[7];
- __u32 link_mode_masks[0];
+ __u32 link_mode_masks[];
};
#endif
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
index 7dcae22..85ce51b 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -240,6 +240,11 @@
ETHTOOL_A_PRIVFLAGS_MAX = __ETHTOOL_A_PRIVFLAGS_CNT - 1
};
enum {
+ ETHTOOL_TCP_DATA_SPLIT_UNKNOWN = 0,
+ ETHTOOL_TCP_DATA_SPLIT_DISABLED,
+ ETHTOOL_TCP_DATA_SPLIT_ENABLED,
+};
+enum {
ETHTOOL_A_RINGS_UNSPEC,
ETHTOOL_A_RINGS_HEADER,
ETHTOOL_A_RINGS_RX_MAX,
@@ -251,6 +256,9 @@
ETHTOOL_A_RINGS_RX_JUMBO,
ETHTOOL_A_RINGS_TX,
ETHTOOL_A_RINGS_RX_BUF_LEN,
+ ETHTOOL_A_RINGS_TCP_DATA_SPLIT,
+ ETHTOOL_A_RINGS_CQE_SIZE,
+ ETHTOOL_A_RINGS_TX_PUSH,
__ETHTOOL_A_RINGS_CNT,
ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
};
diff --git a/libc/kernel/uapi/linux/f2fs.h b/libc/kernel/uapi/linux/f2fs.h
index 76da8f6..3fcd444 100644
--- a/libc/kernel/uapi/linux/f2fs.h
+++ b/libc/kernel/uapi/linux/f2fs.h
@@ -25,7 +25,7 @@
#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2)
#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3)
#define F2FS_IOC_RELEASE_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 4)
-#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5)
+#define F2FS_IOC_ABORT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 5)
#define F2FS_IOC_GARBAGE_COLLECT _IOW(F2FS_IOCTL_MAGIC, 6, __u32)
#define F2FS_IOC_WRITE_CHECKPOINT _IO(F2FS_IOCTL_MAGIC, 7)
#define F2FS_IOC_DEFRAGMENT _IOWR(F2FS_IOCTL_MAGIC, 8, struct f2fs_defragment)
diff --git a/libc/kernel/uapi/linux/fanotify.h b/libc/kernel/uapi/linux/fanotify.h
index 6249292..9815a64 100644
--- a/libc/kernel/uapi/linux/fanotify.h
+++ b/libc/kernel/uapi/linux/fanotify.h
@@ -67,9 +67,12 @@
#define FAN_MARK_IGNORED_MASK 0x00000020
#define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040
#define FAN_MARK_FLUSH 0x00000080
+#define FAN_MARK_EVICTABLE 0x00000200
+#define FAN_MARK_IGNORE 0x00000400
#define FAN_MARK_INODE 0x00000000
#define FAN_MARK_MOUNT 0x00000010
#define FAN_MARK_FILESYSTEM 0x00000100
+#define FAN_MARK_IGNORE_SURV (FAN_MARK_IGNORE | FAN_MARK_IGNORED_SURV_MODIFY)
#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_DONT_FOLLOW | FAN_MARK_ONLYDIR | FAN_MARK_MOUNT | FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY | FAN_MARK_FLUSH)
#define FAN_ALL_EVENTS (FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN)
#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM | FAN_ACCESS_PERM)
@@ -99,7 +102,7 @@
struct fanotify_event_info_fid {
struct fanotify_event_info_header hdr;
__kernel_fsid_t fsid;
- unsigned char handle[0];
+ unsigned char handle[];
};
struct fanotify_event_info_pidfd {
struct fanotify_event_info_header hdr;
diff --git a/libc/kernel/uapi/linux/fiemap.h b/libc/kernel/uapi/linux/fiemap.h
index 4310786..a67a5fe 100644
--- a/libc/kernel/uapi/linux/fiemap.h
+++ b/libc/kernel/uapi/linux/fiemap.h
@@ -34,7 +34,7 @@
__u32 fm_mapped_extents;
__u32 fm_extent_count;
__u32 fm_reserved;
- struct fiemap_extent fm_extents[0];
+ struct fiemap_extent fm_extents[];
};
#define FIEMAP_MAX_OFFSET (~0ULL)
#define FIEMAP_FLAG_SYNC 0x00000001
diff --git a/libc/kernel/uapi/linux/firewire-cdev.h b/libc/kernel/uapi/linux/firewire-cdev.h
index 92957bc..a54191c 100644
--- a/libc/kernel/uapi/linux/firewire-cdev.h
+++ b/libc/kernel/uapi/linux/firewire-cdev.h
@@ -50,7 +50,7 @@
__u32 type;
__u32 rcode;
__u32 length;
- __u32 data[0];
+ __u32 data[];
};
struct fw_cdev_event_request {
__u64 closure;
@@ -59,7 +59,7 @@
__u64 offset;
__u32 handle;
__u32 length;
- __u32 data[0];
+ __u32 data[];
};
struct fw_cdev_event_request2 {
__u64 closure;
@@ -72,14 +72,14 @@
__u32 generation;
__u32 handle;
__u32 length;
- __u32 data[0];
+ __u32 data[];
};
struct fw_cdev_event_iso_interrupt {
__u64 closure;
__u32 type;
__u32 cycle;
__u32 header_length;
- __u32 header[0];
+ __u32 header[];
};
struct fw_cdev_event_iso_interrupt_mc {
__u64 closure;
@@ -98,7 +98,7 @@
__u32 type;
__u32 rcode;
__u32 length;
- __u32 data[0];
+ __u32 data[];
};
union fw_cdev_event {
struct fw_cdev_event_common common;
@@ -207,7 +207,7 @@
#define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24)
struct fw_cdev_iso_packet {
__u32 control;
- __u32 header[0];
+ __u32 header[];
};
struct fw_cdev_queue_iso {
__u64 packets;
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 3bb4183..96f9181 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -63,7 +63,7 @@
__u16 dest_count;
__u16 reserved1;
__u32 reserved2;
- struct file_dedupe_range_info info[0];
+ struct file_dedupe_range_info info[];
};
struct files_stat_struct {
unsigned long nr_files;
diff --git a/libc/kernel/uapi/linux/fscrypt.h b/libc/kernel/uapi/linux/fscrypt.h
index ca42eb3..e6b5358 100644
--- a/libc/kernel/uapi/linux/fscrypt.h
+++ b/libc/kernel/uapi/linux/fscrypt.h
@@ -33,6 +33,7 @@
#define FSCRYPT_MODE_AES_128_CBC 5
#define FSCRYPT_MODE_AES_128_CTS 6
#define FSCRYPT_MODE_ADIANTUM 9
+#define FSCRYPT_MODE_AES_256_HCTR2 10
#define FSCRYPT_POLICY_V1 0
#define FSCRYPT_KEY_DESCRIPTOR_SIZE 8
struct fscrypt_policy_v1 {
diff --git a/libc/kernel/uapi/linux/fsi.h b/libc/kernel/uapi/linux/fsi.h
index fc88464..b080c21 100644
--- a/libc/kernel/uapi/linux/fsi.h
+++ b/libc/kernel/uapi/linux/fsi.h
@@ -48,4 +48,5 @@
#define FSI_SCOM_READ _IOWR('s', 0x01, struct scom_access)
#define FSI_SCOM_WRITE _IOWR('s', 0x02, struct scom_access)
#define FSI_SCOM_RESET _IOW('s', 0x03, __u32)
+#define FSI_SBEFIFO_READ_TIMEOUT_SECONDS _IOW('s', 0x00, __u32)
#endif
diff --git a/libc/kernel/uapi/linux/genetlink.h b/libc/kernel/uapi/linux/genetlink.h
index 2e2137d..0f86331 100644
--- a/libc/kernel/uapi/linux/genetlink.h
+++ b/libc/kernel/uapi/linux/genetlink.h
@@ -81,6 +81,7 @@
CTRL_ATTR_MCAST_GRP_ID,
__CTRL_ATTR_MCAST_GRP_MAX,
};
+#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
enum {
CTRL_ATTR_POLICY_UNSPEC,
CTRL_ATTR_POLICY_DO,
@@ -88,5 +89,5 @@
__CTRL_ATTR_POLICY_DUMP_MAX,
CTRL_ATTR_POLICY_DUMP_MAX = __CTRL_ATTR_POLICY_DUMP_MAX - 1
};
-#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
+#define CTRL_ATTR_POLICY_MAX (__CTRL_ATTR_POLICY_DUMP_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/gpio.h b/libc/kernel/uapi/linux/gpio.h
index 7e010d9..e760321 100644
--- a/libc/kernel/uapi/linux/gpio.h
+++ b/libc/kernel/uapi/linux/gpio.h
@@ -42,6 +42,7 @@
GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN = _BITULL(9),
GPIO_V2_LINE_FLAG_BIAS_DISABLED = _BITULL(10),
GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME = _BITULL(11),
+ GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE = _BITULL(12),
};
struct gpio_v2_line_values {
__aligned_u64 bits;
diff --git a/libc/kernel/uapi/linux/gtp.h b/libc/kernel/uapi/linux/gtp.h
index 3b9416e..20bc3d6 100644
--- a/libc/kernel/uapi/linux/gtp.h
+++ b/libc/kernel/uapi/linux/gtp.h
@@ -23,6 +23,7 @@
GTP_CMD_NEWPDP,
GTP_CMD_DELPDP,
GTP_CMD_GETPDP,
+ GTP_CMD_ECHOREQ,
GTP_CMD_MAX,
};
enum gtp_version {
diff --git a/libc/kernel/uapi/linux/icmp.h b/libc/kernel/uapi/linux/icmp.h
index 8847a48..77cb328 100644
--- a/libc/kernel/uapi/linux/icmp.h
+++ b/libc/kernel/uapi/linux/icmp.h
@@ -84,7 +84,11 @@
} echo;
__be32 gateway;
struct {
+#ifdef __BIONIC__
__be16 __linux_unused;
+#else
+ __be16 __linux_unused;
+#endif
__be16 mtu;
} frag;
__u8 reserved[4];
diff --git a/libc/kernel/uapi/linux/idxd.h b/libc/kernel/uapi/linux/idxd.h
index ad9ed48..c6d6985 100644
--- a/libc/kernel/uapi/linux/idxd.h
+++ b/libc/kernel/uapi/linux/idxd.h
@@ -57,6 +57,11 @@
#define IDXD_OP_FLAG_DRDBK 0x4000
#define IDXD_OP_FLAG_DSTS 0x8000
#define IDXD_OP_FLAG_RD_SRC2_AECS 0x010000
+#define IDXD_OP_FLAG_RD_SRC2_2ND 0x020000
+#define IDXD_OP_FLAG_WR_SRC2_AECS_COMP 0x040000
+#define IDXD_OP_FLAG_WR_SRC2_AECS_OVFL 0x080000
+#define IDXD_OP_FLAG_SRC2_STS 0x100000
+#define IDXD_OP_FLAG_CRC_RFC3720 0x200000
enum dsa_opcode {
DSA_OPCODE_NOOP = 0,
DSA_OPCODE_BATCH,
@@ -82,6 +87,18 @@
IAX_OPCODE_MEMMOVE,
IAX_OPCODE_DECOMPRESS = 0x42,
IAX_OPCODE_COMPRESS,
+ IAX_OPCODE_CRC64,
+ IAX_OPCODE_ZERO_DECOMP_32 = 0x48,
+ IAX_OPCODE_ZERO_DECOMP_16,
+ IAX_OPCODE_ZERO_COMP_32 = 0x4c,
+ IAX_OPCODE_ZERO_COMP_16,
+ IAX_OPCODE_SCAN = 0x50,
+ IAX_OPCODE_SET_MEMBER,
+ IAX_OPCODE_EXTRACT,
+ IAX_OPCODE_SELECT,
+ IAX_OPCODE_RLE_BURST,
+ IAX_OPCODE_FIND_UNIQUE,
+ IAX_OPCODE_EXPAND,
};
enum dsa_completion_status {
DSA_COMP_NONE = 0,
@@ -118,6 +135,7 @@
IAX_COMP_NONE = 0,
IAX_COMP_SUCCESS,
IAX_COMP_PAGE_FAULT_IR = 0x04,
+ IAX_COMP_ANALYTICS_ERROR = 0x0a,
IAX_COMP_OUTBUF_OVERFLOW,
IAX_COMP_BAD_OPCODE = 0x10,
IAX_COMP_INVALID_FLAGS,
@@ -138,7 +156,10 @@
IAX_COMP_WATCHDOG,
IAX_COMP_INVALID_COMP_FLAG = 0x30,
IAX_COMP_INVALID_FILTER_FLAG,
- IAX_COMP_INVALID_NUM_ELEMS = 0x33,
+ IAX_COMP_INVALID_INPUT_SIZE,
+ IAX_COMP_INVALID_NUM_ELEMS,
+ IAX_COMP_INVALID_SRC1_WIDTH,
+ IAX_COMP_INVALID_INVERT_OUT,
};
#define DSA_COMP_STATUS_MASK 0x7f
#define DSA_COMP_STATUS_WRITE 0x80
@@ -291,8 +312,12 @@
uint32_t output_size;
uint8_t output_bits;
uint8_t rsvd3;
- uint16_t rsvd4;
- uint64_t rsvd5[4];
+ uint16_t xor_csum;
+ uint32_t crc;
+ uint32_t min;
+ uint32_t max;
+ uint32_t sum;
+ uint64_t rsvd4[2];
} __attribute__((packed));
struct iax_raw_completion_record {
uint64_t field[8];
diff --git a/libc/kernel/uapi/linux/if_addr.h b/libc/kernel/uapi/linux/if_addr.h
index 6a6b640..a225e69 100644
--- a/libc/kernel/uapi/linux/if_addr.h
+++ b/libc/kernel/uapi/linux/if_addr.h
@@ -39,6 +39,7 @@
IFA_FLAGS,
IFA_RT_PRIORITY,
IFA_TARGET_NETNSID,
+ IFA_PROTO,
__IFA_MAX,
};
#define IFA_MAX (__IFA_MAX - 1)
@@ -63,4 +64,8 @@
};
#define IFA_RTA(r) ((struct rtattr *) (((char *) (r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg))
+#define IFAPROT_UNSPEC 0
+#define IFAPROT_KERNEL_LO 1
+#define IFAPROT_KERNEL_RA 2
+#define IFAPROT_KERNEL_LL 3
#endif
diff --git a/libc/kernel/uapi/linux/if_alg.h b/libc/kernel/uapi/linux/if_alg.h
index 6530a16..237fe6e 100644
--- a/libc/kernel/uapi/linux/if_alg.h
+++ b/libc/kernel/uapi/linux/if_alg.h
@@ -35,7 +35,7 @@
};
struct af_alg_iv {
__u32 ivlen;
- __u8 iv[0];
+ __u8 iv[];
};
#define ALG_SET_KEY 1
#define ALG_SET_IV 2
diff --git a/libc/kernel/uapi/linux/if_arcnet.h b/libc/kernel/uapi/linux/if_arcnet.h
index 6aece37..65b07e1 100644
--- a/libc/kernel/uapi/linux/if_arcnet.h
+++ b/libc/kernel/uapi/linux/if_arcnet.h
@@ -40,18 +40,18 @@
__u8 proto;
__u8 split_flag;
__be16 sequence;
- __u8 payload[0];
+ __u8 payload[];
};
#define RFC1201_HDR_SIZE 4
struct arc_rfc1051 {
__u8 proto;
- __u8 payload[0];
+ __u8 payload[];
};
#define RFC1051_HDR_SIZE 1
struct arc_eth_encap {
__u8 proto;
struct ethhdr eth;
- __u8 payload[0];
+ __u8 payload[];
};
#define ETH_ENCAP_HDR_SIZE 14
struct arc_cap {
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 2054fb3..0f08866 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -108,6 +108,7 @@
IFLA_BRIDGE_VLAN_TUNNEL_INFO,
IFLA_BRIDGE_MRP,
IFLA_BRIDGE_CFM,
+ IFLA_BRIDGE_MST,
__IFLA_BRIDGE_MAX,
};
#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
@@ -384,6 +385,19 @@
__IFLA_BRIDGE_CFM_CC_PEER_STATUS_MAX,
};
#define IFLA_BRIDGE_CFM_CC_PEER_STATUS_MAX (__IFLA_BRIDGE_CFM_CC_PEER_STATUS_MAX - 1)
+enum {
+ IFLA_BRIDGE_MST_UNSPEC,
+ IFLA_BRIDGE_MST_ENTRY,
+ __IFLA_BRIDGE_MST_MAX,
+};
+#define IFLA_BRIDGE_MST_MAX (__IFLA_BRIDGE_MST_MAX - 1)
+enum {
+ IFLA_BRIDGE_MST_ENTRY_UNSPEC,
+ IFLA_BRIDGE_MST_ENTRY_MSTI,
+ IFLA_BRIDGE_MST_ENTRY_STATE,
+ __IFLA_BRIDGE_MST_ENTRY_MAX,
+};
+#define IFLA_BRIDGE_MST_ENTRY_MAX (__IFLA_BRIDGE_MST_ENTRY_MAX - 1)
struct bridge_stp_xstats {
__u64 transition_blk;
__u64 transition_fwd;
@@ -460,6 +474,7 @@
BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS,
BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE,
+ BRIDGE_VLANDB_GOPTS_MSTI,
__BRIDGE_VLANDB_GOPTS_MAX
};
#define BRIDGE_VLANDB_GOPTS_MAX (__BRIDGE_VLANDB_GOPTS_MAX - 1)
@@ -599,6 +614,7 @@
enum br_boolopt_id {
BR_BOOLOPT_NO_LL_LEARN,
BR_BOOLOPT_MCAST_VLAN_SNOOPING,
+ BR_BOOLOPT_MST_ENABLE,
BR_BOOLOPT_MAX
};
struct br_boolopt_multi {
diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h
index 1f7f8f2..d35509e 100644
--- a/libc/kernel/uapi/linux/if_ether.h
+++ b/libc/kernel/uapi/linux/if_ether.h
@@ -67,8 +67,10 @@
#define ETH_P_LINK_CTL 0x886c
#define ETH_P_ATMFATE 0x8884
#define ETH_P_PAE 0x888E
+#define ETH_P_PROFINET 0x8892
#define ETH_P_REALTEK 0x8899
#define ETH_P_AOE 0x88A2
+#define ETH_P_ETHERCAT 0x88A4
#define ETH_P_8021AD 0x88A8
#define ETH_P_802_EX1 0x88B5
#define ETH_P_PREAUTH 0x88C7
@@ -95,6 +97,7 @@
#define ETH_P_QINQ3 0x9300
#define ETH_P_EDSA 0xDADA
#define ETH_P_DSA_8021Q 0xDADB
+#define ETH_P_DSA_A5PSW 0xE001
#define ETH_P_IFE 0xED3E
#define ETH_P_AF_IUCV 0xFBFB
#define ETH_P_802_3_MIN 0x0600
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 7e413ae..52f8ca3 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -71,6 +71,18 @@
__u64 rx_compressed;
__u64 tx_compressed;
__u64 rx_nohandler;
+ __u64 rx_otherhost_dropped;
+};
+struct rtnl_hw_stats64 {
+ __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 multicast;
};
struct rtnl_link_ifmap {
__u64 mem_start;
@@ -151,6 +163,8 @@
IFLA_PARENT_DEV_NAME,
IFLA_PARENT_DEV_BUS_NAME,
IFLA_GRO_MAX_SIZE,
+ IFLA_TSO_MAX_SIZE,
+ IFLA_TSO_MAX_SEGS,
__IFLA_MAX
};
#define IFLA_MAX (__IFLA_MAX - 1)
@@ -289,6 +303,7 @@
IFLA_BRPORT_MRP_IN_OPEN,
IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
+ IFLA_BRPORT_LOCKED,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -428,6 +443,44 @@
};
#define IPVLAN_F_PRIVATE 0x01
#define IPVLAN_F_VEPA 0x02
+struct tunnel_msg {
+ __u8 family;
+ __u8 flags;
+ __u16 reserved2;
+ __u32 ifindex;
+};
+#define TUNNEL_MSG_FLAG_STATS 0x01
+#define TUNNEL_MSG_VALID_USER_FLAGS TUNNEL_MSG_FLAG_STATS
+enum {
+ VNIFILTER_ENTRY_STATS_UNSPEC,
+ VNIFILTER_ENTRY_STATS_RX_BYTES,
+ VNIFILTER_ENTRY_STATS_RX_PKTS,
+ VNIFILTER_ENTRY_STATS_RX_DROPS,
+ VNIFILTER_ENTRY_STATS_RX_ERRORS,
+ VNIFILTER_ENTRY_STATS_TX_BYTES,
+ VNIFILTER_ENTRY_STATS_TX_PKTS,
+ VNIFILTER_ENTRY_STATS_TX_DROPS,
+ VNIFILTER_ENTRY_STATS_TX_ERRORS,
+ VNIFILTER_ENTRY_STATS_PAD,
+ __VNIFILTER_ENTRY_STATS_MAX
+};
+#define VNIFILTER_ENTRY_STATS_MAX (__VNIFILTER_ENTRY_STATS_MAX - 1)
+enum {
+ VXLAN_VNIFILTER_ENTRY_UNSPEC,
+ VXLAN_VNIFILTER_ENTRY_START,
+ VXLAN_VNIFILTER_ENTRY_END,
+ VXLAN_VNIFILTER_ENTRY_GROUP,
+ VXLAN_VNIFILTER_ENTRY_GROUP6,
+ VXLAN_VNIFILTER_ENTRY_STATS,
+ __VXLAN_VNIFILTER_ENTRY_MAX
+};
+#define VXLAN_VNIFILTER_ENTRY_MAX (__VXLAN_VNIFILTER_ENTRY_MAX - 1)
+enum {
+ VXLAN_VNIFILTER_UNSPEC,
+ VXLAN_VNIFILTER_ENTRY,
+ __VXLAN_VNIFILTER_MAX
+};
+#define VXLAN_VNIFILTER_MAX (__VXLAN_VNIFILTER_MAX - 1)
enum {
IFLA_VXLAN_UNSPEC,
IFLA_VXLAN_ID,
@@ -459,6 +512,7 @@
IFLA_VXLAN_GPE,
IFLA_VXLAN_TTL_INHERIT,
IFLA_VXLAN_DF,
+ IFLA_VXLAN_VNIFILTER,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
@@ -488,6 +542,7 @@
IFLA_GENEVE_LABEL,
IFLA_GENEVE_TTL_INHERIT,
IFLA_GENEVE_DF,
+ IFLA_GENEVE_INNER_PROTO_INHERIT,
__IFLA_GENEVE_MAX
};
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
@@ -523,6 +578,8 @@
IFLA_GTP_FD1,
IFLA_GTP_PDP_HASHSIZE,
IFLA_GTP_ROLE,
+ IFLA_GTP_CREATE_SOCKETS,
+ IFLA_GTP_RESTART_COUNT,
__IFLA_GTP_MAX,
};
#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
@@ -558,6 +615,7 @@
IFLA_BOND_PEER_NOTIF_DELAY,
IFLA_BOND_AD_LACP_ACTIVE,
IFLA_BOND_MISSED_MAX,
+ IFLA_BOND_NS_IP6_TARGET,
__IFLA_BOND_MAX,
};
#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
@@ -581,6 +639,7 @@
IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
+ IFLA_BOND_SLAVE_PRIO,
__IFLA_BOND_SLAVE_MAX,
};
#define IFLA_BOND_SLAVE_MAX (__IFLA_BOND_SLAVE_MAX - 1)
@@ -777,6 +836,13 @@
#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
#define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR - 1))
enum {
+ IFLA_STATS_GETSET_UNSPEC,
+ IFLA_STATS_GET_FILTERS,
+ IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS,
+ __IFLA_STATS_GETSET_MAX,
+};
+#define IFLA_STATS_GETSET_MAX (__IFLA_STATS_GETSET_MAX - 1)
+enum {
LINK_XSTATS_TYPE_UNSPEC,
LINK_XSTATS_TYPE_BRIDGE,
LINK_XSTATS_TYPE_BOND,
@@ -786,9 +852,18 @@
enum {
IFLA_OFFLOAD_XSTATS_UNSPEC,
IFLA_OFFLOAD_XSTATS_CPU_HIT,
+ IFLA_OFFLOAD_XSTATS_HW_S_INFO,
+ IFLA_OFFLOAD_XSTATS_L3_STATS,
__IFLA_OFFLOAD_XSTATS_MAX
};
#define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1)
+enum {
+ IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC,
+ IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST,
+ IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED,
+ __IFLA_OFFLOAD_XSTATS_HW_S_INFO_MAX,
+};
+#define IFLA_OFFLOAD_XSTATS_HW_S_INFO_MAX (__IFLA_OFFLOAD_XSTATS_HW_S_INFO_MAX - 1)
#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0)
#define XDP_FLAGS_SKB_MODE (1U << 1)
#define XDP_FLAGS_DRV_MODE (1U << 2)
diff --git a/libc/kernel/uapi/linux/if_pppox.h b/libc/kernel/uapi/linux/if_pppox.h
index 40d25e8..b6c076b 100644
--- a/libc/kernel/uapi/linux/if_pppox.h
+++ b/libc/kernel/uapi/linux/if_pppox.h
@@ -82,7 +82,7 @@
struct pppoe_tag {
__be16 tag_type;
__be16 tag_len;
- char tag_data[0];
+ char tag_data[];
} __attribute__((packed));
#define PTT_EOL __cpu_to_be16(0x0000)
#define PTT_SRV_NAME __cpu_to_be16(0x0101)
@@ -107,7 +107,7 @@
__u8 code;
__be16 sid;
__be16 length;
- struct pppoe_tag tag[0];
+ struct pppoe_tag tag[];
} __packed;
#define PPPOE_SES_HLEN 8
#endif
diff --git a/libc/kernel/uapi/linux/if_tun.h b/libc/kernel/uapi/linux/if_tun.h
index d1a8f9e..dda0830 100644
--- a/libc/kernel/uapi/linux/if_tun.h
+++ b/libc/kernel/uapi/linux/if_tun.h
@@ -57,6 +57,7 @@
#define IFF_TAP 0x0002
#define IFF_NAPI 0x0010
#define IFF_NAPI_FRAGS 0x0020
+#define IFF_NO_CARRIER 0x0040
#define IFF_NO_PI 0x1000
#define IFF_ONE_QUEUE 0x2000
#define IFF_VNET_HDR 0x4000
@@ -81,6 +82,6 @@
struct tun_filter {
__u16 flags;
__u16 count;
- __u8 addr[0][ETH_ALEN];
+ __u8 addr[][ETH_ALEN];
};
#endif
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index 8e1847f..01c2dc9 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -169,5 +169,6 @@
#define TUNNEL_VXLAN_OPT __cpu_to_be16(0x1000)
#define TUNNEL_NOCACHE __cpu_to_be16(0x2000)
#define TUNNEL_ERSPAN_OPT __cpu_to_be16(0x4000)
-#define TUNNEL_OPTIONS_PRESENT (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT | TUNNEL_ERSPAN_OPT)
+#define TUNNEL_GTP_OPT __cpu_to_be16(0x8000)
+#define TUNNEL_OPTIONS_PRESENT (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT | TUNNEL_ERSPAN_OPT | TUNNEL_GTP_OPT)
#endif
diff --git a/libc/kernel/uapi/linux/igmp.h b/libc/kernel/uapi/linux/igmp.h
index 885b0f8..71c2c8d 100644
--- a/libc/kernel/uapi/linux/igmp.h
+++ b/libc/kernel/uapi/linux/igmp.h
@@ -37,7 +37,7 @@
__u8 grec_auxwords;
__be16 grec_nsrcs;
__be32 grec_mca;
- __be32 grec_src[0];
+ __be32 grec_src[];
};
struct igmpv3_report {
__u8 type;
@@ -45,7 +45,7 @@
__sum16 csum;
__be16 resv2;
__be16 ngrec;
- struct igmpv3_grec grec[0];
+ struct igmpv3_grec grec[];
};
struct igmpv3_query {
__u8 type;
@@ -61,7 +61,7 @@
#endif
__u8 qqic;
__be16 nsrcs;
- __be32 srcs[0];
+ __be32 srcs[];
};
#define IGMP_HOST_MEMBERSHIP_QUERY 0x11
#define IGMP_HOST_MEMBERSHIP_REPORT 0x12
diff --git a/libc/kernel/uapi/linux/iio/types.h b/libc/kernel/uapi/linux/iio/types.h
index 22409a7..aa66d50 100644
--- a/libc/kernel/uapi/linux/iio/types.h
+++ b/libc/kernel/uapi/linux/iio/types.h
@@ -109,6 +109,7 @@
IIO_EV_TYPE_THRESH_ADAPTIVE,
IIO_EV_TYPE_MAG_ADAPTIVE,
IIO_EV_TYPE_CHANGE,
+ IIO_EV_TYPE_MAG_REFERENCED,
};
enum iio_event_direction {
IIO_EV_DIR_EITHER,
diff --git a/libc/kernel/uapi/linux/inet_diag.h b/libc/kernel/uapi/linux/inet_diag.h
index 8656dd4..27f390b 100644
--- a/libc/kernel/uapi/linux/inet_diag.h
+++ b/libc/kernel/uapi/linux/inet_diag.h
@@ -89,7 +89,7 @@
__u8 family;
__u8 prefix_len;
int port;
- __be32 addr[0];
+ __be32 addr[];
};
struct inet_diag_markcond {
__u32 mark;
diff --git a/libc/kernel/uapi/linux/inotify.h b/libc/kernel/uapi/linux/inotify.h
index eb9ac3c..3b4b577 100644
--- a/libc/kernel/uapi/linux/inotify.h
+++ b/libc/kernel/uapi/linux/inotify.h
@@ -25,7 +25,7 @@
__u32 mask;
__u32 cookie;
__u32 len;
- char name[0];
+ char name[];
};
#define IN_ACCESS 0x00000001
#define IN_MODIFY 0x00000002
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index 34cd23c..4b251df 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -580,6 +580,21 @@
#define KEY_ONSCREEN_KEYBOARD 0x278
#define KEY_PRIVACY_SCREEN_TOGGLE 0x279
#define KEY_SELECTIVE_SCREENSHOT 0x27a
+#define KEY_NEXT_ELEMENT 0x27b
+#define KEY_PREVIOUS_ELEMENT 0x27c
+#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
+#define KEY_MARK_WAYPOINT 0x27e
+#define KEY_SOS 0x27f
+#define KEY_NAV_CHART 0x280
+#define KEY_FISHING_CHART 0x281
+#define KEY_SINGLE_RANGE_RADAR 0x282
+#define KEY_DUAL_RANGE_RADAR 0x283
+#define KEY_RADAR_OVERLAY 0x284
+#define KEY_TRADITIONAL_SONAR 0x285
+#define KEY_CLEARVU_SONAR 0x286
+#define KEY_SIDEVU_SONAR 0x287
+#define KEY_NAV_INFO 0x288
+#define KEY_BRIGHTNESS_MENU 0x289
#define KEY_MACRO1 0x290
#define KEY_MACRO2 0x291
#define KEY_MACRO3 0x292
diff --git a/libc/kernel/uapi/linux/input.h b/libc/kernel/uapi/linux/input.h
index fe17226..4858c81 100644
--- a/libc/kernel/uapi/linux/input.h
+++ b/libc/kernel/uapi/linux/input.h
@@ -125,6 +125,7 @@
#define BUS_RMI 0x1D
#define BUS_CEC 0x1E
#define BUS_INTEL_ISHTP 0x1F
+#define BUS_AMD_SFH 0x20
#define MT_TOOL_FINGER 0x00
#define MT_TOOL_PEN 0x01
#define MT_TOOL_PALM 0x02
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index 96944f8..4d52cf0 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -20,6 +20,10 @@
#define LINUX_IO_URING_H
#include <linux/fs.h>
#include <linux/types.h>
+#include <linux/time_types.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
struct io_uring_sqe {
__u8 opcode;
__u8 flags;
@@ -28,6 +32,10 @@
union {
__u64 off;
__u64 addr2;
+ struct {
+ __u32 cmd_op;
+ __u32 __pad1;
+ };
};
union {
__u64 addr;
@@ -51,6 +59,8 @@
__u32 rename_flags;
__u32 unlink_flags;
__u32 hardlink_flags;
+ __u32 xattr_flags;
+ __u32 msg_ring_flags;
};
__u64 user_data;
union {
@@ -61,9 +71,20 @@
union {
__s32 splice_fd_in;
__u32 file_index;
+ struct {
+ __u16 addr_len;
+ __u16 __pad3[1];
+ };
};
- __u64 __pad2[2];
+ union {
+ struct {
+ __u64 addr3;
+ __u64 __pad2[1];
+ };
+ __u8 cmd[0];
+ };
};
+#define IORING_FILE_INDEX_ALLOC (~0U)
enum {
IOSQE_FIXED_FILE_BIT,
IOSQE_IO_DRAIN_BIT,
@@ -87,7 +108,13 @@
#define IORING_SETUP_CLAMP (1U << 4)
#define IORING_SETUP_ATTACH_WQ (1U << 5)
#define IORING_SETUP_R_DISABLED (1U << 6)
-enum {
+#define IORING_SETUP_SUBMIT_ALL (1U << 7)
+#define IORING_SETUP_COOP_TASKRUN (1U << 8)
+#define IORING_SETUP_TASKRUN_FLAG (1U << 9)
+#define IORING_SETUP_SQE128 (1U << 10)
+#define IORING_SETUP_CQE32 (1U << 11)
+#define IORING_SETUP_SINGLE_ISSUER (1U << 12)
+enum io_uring_op {
IORING_OP_NOP,
IORING_OP_READV,
IORING_OP_WRITEV,
@@ -128,6 +155,14 @@
IORING_OP_MKDIRAT,
IORING_OP_SYMLINKAT,
IORING_OP_LINKAT,
+ IORING_OP_MSG_RING,
+ IORING_OP_FSETXATTR,
+ IORING_OP_SETXATTR,
+ IORING_OP_FGETXATTR,
+ IORING_OP_GETXATTR,
+ IORING_OP_SOCKET,
+ IORING_OP_URING_CMD,
+ IORING_OP_SEND_ZC,
IORING_OP_LAST,
};
#define IORING_FSYNC_DATASYNC (1U << 0)
@@ -143,13 +178,30 @@
#define IORING_POLL_ADD_MULTI (1U << 0)
#define IORING_POLL_UPDATE_EVENTS (1U << 1)
#define IORING_POLL_UPDATE_USER_DATA (1U << 2)
+#define IORING_POLL_ADD_LEVEL (1U << 3)
+#define IORING_ASYNC_CANCEL_ALL (1U << 0)
+#define IORING_ASYNC_CANCEL_FD (1U << 1)
+#define IORING_ASYNC_CANCEL_ANY (1U << 2)
+#define IORING_ASYNC_CANCEL_FD_FIXED (1U << 3)
+#define IORING_RECVSEND_POLL_FIRST (1U << 0)
+#define IORING_RECV_MULTISHOT (1U << 1)
+#define IORING_RECVSEND_FIXED_BUF (1U << 2)
+#define IORING_ACCEPT_MULTISHOT (1U << 0)
+enum {
+ IORING_MSG_DATA,
+ IORING_MSG_SEND_FD,
+};
+#define IORING_MSG_RING_CQE_SKIP (1U << 0)
struct io_uring_cqe {
__u64 user_data;
__s32 res;
__u32 flags;
+ __u64 big_cqe[];
};
#define IORING_CQE_F_BUFFER (1U << 0)
#define IORING_CQE_F_MORE (1U << 1)
+#define IORING_CQE_F_SOCK_NONEMPTY (1U << 2)
+#define IORING_CQE_F_NOTIF (1U << 3)
enum {
IORING_CQE_BUFFER_SHIFT = 16,
};
@@ -169,6 +221,7 @@
};
#define IORING_SQ_NEED_WAKEUP (1U << 0)
#define IORING_SQ_CQ_OVERFLOW (1U << 1)
+#define IORING_SQ_TASKRUN (1U << 2)
struct io_cqring_offsets {
__u32 head;
__u32 tail;
@@ -185,6 +238,7 @@
#define IORING_ENTER_SQ_WAKEUP (1U << 1)
#define IORING_ENTER_SQ_WAIT (1U << 2)
#define IORING_ENTER_EXT_ARG (1U << 3)
+#define IORING_ENTER_REGISTERED_RING (1U << 4)
struct io_uring_params {
__u32 sq_entries;
__u32 cq_entries;
@@ -209,6 +263,7 @@
#define IORING_FEAT_NATIVE_WORKERS (1U << 9)
#define IORING_FEAT_RSRC_TAGS (1U << 10)
#define IORING_FEAT_CQE_SKIP (1U << 11)
+#define IORING_FEAT_LINKED_FILE (1U << 12)
enum {
IORING_REGISTER_BUFFERS = 0,
IORING_UNREGISTER_BUFFERS = 1,
@@ -230,6 +285,12 @@
IORING_REGISTER_IOWQ_AFF = 17,
IORING_UNREGISTER_IOWQ_AFF = 18,
IORING_REGISTER_IOWQ_MAX_WORKERS = 19,
+ IORING_REGISTER_RING_FDS = 20,
+ IORING_UNREGISTER_RING_FDS = 21,
+ IORING_REGISTER_PBUF_RING = 22,
+ IORING_UNREGISTER_PBUF_RING = 23,
+ IORING_REGISTER_SYNC_CANCEL = 24,
+ IORING_REGISTER_FILE_ALLOC_RANGE = 25,
IORING_REGISTER_LAST
};
enum {
@@ -241,9 +302,10 @@
__u32 resv;
__aligned_u64 fds;
};
+#define IORING_RSRC_REGISTER_SPARSE (1U << 0)
struct io_uring_rsrc_register {
__u32 nr;
- __u32 resv;
+ __u32 flags;
__u64 resv2;
__aligned_u64 data;
__aligned_u64 tags;
@@ -261,6 +323,17 @@
__u32 nr;
__u32 resv2;
};
+struct io_uring_notification_slot {
+ __u64 tag;
+ __u64 resv[3];
+};
+struct io_uring_notification_register {
+ __u32 nr_slots;
+ __u32 resv;
+ __u64 resv2;
+ __u64 data;
+ __u64 resv3;
+};
#define IORING_REGISTER_FILES_SKIP (- 2)
#define IO_URING_OP_SUPPORTED (1U << 0)
struct io_uring_probe_op {
@@ -274,7 +347,7 @@
__u8 ops_len;
__u16 resv;
__u32 resv2[3];
- struct io_uring_probe_op ops[0];
+ struct io_uring_probe_op ops[];
};
struct io_uring_restriction {
__u16 opcode;
@@ -286,6 +359,30 @@
__u8 resv;
__u32 resv2[3];
};
+struct io_uring_buf {
+ __u64 addr;
+ __u32 len;
+ __u16 bid;
+ __u16 resv;
+};
+struct io_uring_buf_ring {
+ union {
+ struct {
+ __u64 resv1;
+ __u32 resv2;
+ __u16 resv3;
+ __u16 tail;
+ };
+ struct io_uring_buf bufs[0];
+ };
+};
+struct io_uring_buf_reg {
+ __u64 ring_addr;
+ __u32 ring_entries;
+ __u16 bgid;
+ __u16 pad;
+ __u64 resv[3];
+};
enum {
IORING_RESTRICTION_REGISTER_OP = 0,
IORING_RESTRICTION_SQE_OP = 1,
@@ -299,4 +396,25 @@
__u32 pad;
__u64 ts;
};
+struct io_uring_sync_cancel_reg {
+ __u64 addr;
+ __s32 fd;
+ __u32 flags;
+ struct __kernel_timespec timeout;
+ __u64 pad[4];
+};
+struct io_uring_file_index_range {
+ __u32 off;
+ __u32 len;
+ __u64 resv;
+};
+struct io_uring_recvmsg_out {
+ __u32 namelen;
+ __u32 controllen;
+ __u32 payloadlen;
+ __u32 flags;
+};
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/libc/kernel/uapi/linux/ioam6_iptunnel.h b/libc/kernel/uapi/linux/ioam6_iptunnel.h
index 7426225..ec1a6a8 100644
--- a/libc/kernel/uapi/linux/ioam6_iptunnel.h
+++ b/libc/kernel/uapi/linux/ioam6_iptunnel.h
@@ -32,6 +32,10 @@
IOAM6_IPTUNNEL_MODE,
IOAM6_IPTUNNEL_DST,
IOAM6_IPTUNNEL_TRACE,
+#define IOAM6_IPTUNNEL_FREQ_MIN 1
+#define IOAM6_IPTUNNEL_FREQ_MAX 1000000
+ IOAM6_IPTUNNEL_FREQ_K,
+ IOAM6_IPTUNNEL_FREQ_N,
__IOAM6_IPTUNNEL_MAX,
};
#define IOAM6_IPTUNNEL_MAX (__IOAM6_IPTUNNEL_MAX - 1)
diff --git a/libc/kernel/uapi/linux/iommu.h b/libc/kernel/uapi/linux/iommu.h
index 0a0af92..0304a32 100644
--- a/libc/kernel/uapi/linux/iommu.h
+++ b/libc/kernel/uapi/linux/iommu.h
@@ -85,76 +85,4 @@
__u32 grpid;
__u32 code;
};
-enum iommu_inv_granularity {
- IOMMU_INV_GRANU_DOMAIN,
- IOMMU_INV_GRANU_PASID,
- IOMMU_INV_GRANU_ADDR,
- IOMMU_INV_GRANU_NR,
-};
-struct iommu_inv_addr_info {
-#define IOMMU_INV_ADDR_FLAGS_PASID (1 << 0)
-#define IOMMU_INV_ADDR_FLAGS_ARCHID (1 << 1)
-#define IOMMU_INV_ADDR_FLAGS_LEAF (1 << 2)
- __u32 flags;
- __u32 archid;
- __u64 pasid;
- __u64 addr;
- __u64 granule_size;
- __u64 nb_granules;
-};
-struct iommu_inv_pasid_info {
-#define IOMMU_INV_PASID_FLAGS_PASID (1 << 0)
-#define IOMMU_INV_PASID_FLAGS_ARCHID (1 << 1)
- __u32 flags;
- __u32 archid;
- __u64 pasid;
-};
-struct iommu_cache_invalidate_info {
- __u32 argsz;
-#define IOMMU_CACHE_INVALIDATE_INFO_VERSION_1 1
- __u32 version;
-#define IOMMU_CACHE_INV_TYPE_IOTLB (1 << 0)
-#define IOMMU_CACHE_INV_TYPE_DEV_IOTLB (1 << 1)
-#define IOMMU_CACHE_INV_TYPE_PASID (1 << 2)
-#define IOMMU_CACHE_INV_TYPE_NR (3)
- __u8 cache;
- __u8 granularity;
- __u8 padding[6];
- union {
- struct iommu_inv_pasid_info pasid_info;
- struct iommu_inv_addr_info addr_info;
- } granu;
-};
-struct iommu_gpasid_bind_data_vtd {
-#define IOMMU_SVA_VTD_GPASID_SRE (1 << 0)
-#define IOMMU_SVA_VTD_GPASID_EAFE (1 << 1)
-#define IOMMU_SVA_VTD_GPASID_PCD (1 << 2)
-#define IOMMU_SVA_VTD_GPASID_PWT (1 << 3)
-#define IOMMU_SVA_VTD_GPASID_EMTE (1 << 4)
-#define IOMMU_SVA_VTD_GPASID_CD (1 << 5)
-#define IOMMU_SVA_VTD_GPASID_WPE (1 << 6)
-#define IOMMU_SVA_VTD_GPASID_LAST (1 << 7)
- __u64 flags;
- __u32 pat;
- __u32 emt;
-};
-#define IOMMU_SVA_VTD_GPASID_MTS_MASK (IOMMU_SVA_VTD_GPASID_CD | IOMMU_SVA_VTD_GPASID_EMTE | IOMMU_SVA_VTD_GPASID_PCD | IOMMU_SVA_VTD_GPASID_PWT)
-struct iommu_gpasid_bind_data {
- __u32 argsz;
-#define IOMMU_GPASID_BIND_VERSION_1 1
- __u32 version;
-#define IOMMU_PASID_FORMAT_INTEL_VTD 1
-#define IOMMU_PASID_FORMAT_LAST 2
- __u32 format;
- __u32 addr_width;
-#define IOMMU_SVA_GPASID_VAL (1 << 0)
- __u64 flags;
- __u64 gpgd;
- __u64 hpasid;
- __u64 gpasid;
- __u8 padding[8];
- union {
- struct iommu_gpasid_bind_data_vtd vtd;
- } vendor;
-};
#endif
diff --git a/libc/kernel/uapi/linux/ip.h b/libc/kernel/uapi/linux/ip.h
index 9571cac..b6aef50 100644
--- a/libc/kernel/uapi/linux/ip.h
+++ b/libc/kernel/uapi/linux/ip.h
@@ -95,12 +95,12 @@
__be16 reserved;
__be32 spi;
__be32 seq_no;
- __u8 auth_data[0];
+ __u8 auth_data[];
};
struct ip_esp_hdr {
__be32 spi;
__be32 seq_no;
- __u8 enc_data[0];
+ __u8 enc_data[];
};
struct ip_comp_hdr {
__u8 nexthdr;
diff --git a/libc/kernel/uapi/linux/ip_vs.h b/libc/kernel/uapi/linux/ip_vs.h
index 6e3defe..916fcf0 100644
--- a/libc/kernel/uapi/linux/ip_vs.h
+++ b/libc/kernel/uapi/linux/ip_vs.h
@@ -159,11 +159,11 @@
__be16 port;
__u32 fwmark;
unsigned int num_dests;
- struct ip_vs_dest_entry entrytable[0];
+ struct ip_vs_dest_entry entrytable[];
};
struct ip_vs_get_services {
unsigned int num_services;
- struct ip_vs_service_entry entrytable[0];
+ struct ip_vs_service_entry entrytable[];
};
struct ip_vs_timeout_user {
int tcp_timeout;
diff --git a/libc/kernel/uapi/linux/ipv6.h b/libc/kernel/uapi/linux/ipv6.h
index b3db9ce..757cbda 100644
--- a/libc/kernel/uapi/linux/ipv6.h
+++ b/libc/kernel/uapi/linux/ipv6.h
@@ -148,6 +148,7 @@
DEVCONF_IOAM6_ID,
DEVCONF_IOAM6_ID_WIDE,
DEVCONF_NDISC_EVICT_NOCARRIER,
+ DEVCONF_ACCEPT_UNTRACKED_NA,
DEVCONF_MAX
};
#endif
diff --git a/libc/kernel/uapi/linux/iso_fs.h b/libc/kernel/uapi/linux/iso_fs.h
index 8227031..f9c4f48 100644
--- a/libc/kernel/uapi/linux/iso_fs.h
+++ b/libc/kernel/uapi/linux/iso_fs.h
@@ -132,7 +132,7 @@
__u8 name_len[2];
__u8 extent[4];
__u8 parent[2];
- char name[0];
+ char name[];
} __attribute__((packed));
struct iso_directory_record {
__u8 length[ISODCL(1, 1)];
@@ -145,7 +145,7 @@
__u8 interleave[ISODCL(28, 28)];
__u8 volume_sequence_number[ISODCL(29, 32)];
__u8 name_len[ISODCL(33, 33)];
- char name[0];
+ char name[];
} __attribute__((packed));
#define ISOFS_BLOCK_BITS 11
#define ISOFS_BLOCK_SIZE 2048
diff --git a/libc/kernel/uapi/linux/jffs2.h b/libc/kernel/uapi/linux/jffs2.h
index 698f953..643aa2e 100644
--- a/libc/kernel/uapi/linux/jffs2.h
+++ b/libc/kernel/uapi/linux/jffs2.h
@@ -86,7 +86,7 @@
__u8 unused[2];
jint32_t node_crc;
jint32_t name_crc;
- __u8 name[0];
+ __u8 name[];
};
struct jffs2_raw_inode {
jint16_t magic;
@@ -110,7 +110,7 @@
jint16_t flags;
jint32_t data_crc;
jint32_t node_crc;
- __u8 data[0];
+ __u8 data[];
};
struct jffs2_raw_xattr {
jint16_t magic;
@@ -124,7 +124,7 @@
jint16_t value_len;
jint32_t data_crc;
jint32_t node_crc;
- __u8 data[0];
+ __u8 data[];
} __attribute__((packed));
struct jffs2_raw_xref {
jint16_t magic;
@@ -146,7 +146,7 @@
jint32_t padded;
jint32_t sum_crc;
jint32_t node_crc;
- jint32_t sum[0];
+ jint32_t sum[];
};
union jffs2_node_union {
struct jffs2_raw_inode i;
diff --git a/libc/kernel/uapi/linux/kcov.h b/libc/kernel/uapi/linux/kcov.h
index cf2660b..5b6f6b1 100644
--- a/libc/kernel/uapi/linux/kcov.h
+++ b/libc/kernel/uapi/linux/kcov.h
@@ -24,7 +24,7 @@
__u32 area_size;
__u32 num_handles;
__aligned_u64 common_handle;
- __aligned_u64 handles[0];
+ __aligned_u64 handles[];
};
#define KCOV_REMOTE_MAX_HANDLES 0x100
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long)
diff --git a/libc/kernel/uapi/linux/kexec.h b/libc/kernel/uapi/linux/kexec.h
index 2e3bd0c..438c07b 100644
--- a/libc/kernel/uapi/linux/kexec.h
+++ b/libc/kernel/uapi/linux/kexec.h
@@ -40,11 +40,12 @@
#define KEXEC_ARCH_MIPS (8 << 16)
#define KEXEC_ARCH_AARCH64 (183 << 16)
#define KEXEC_ARCH_RISCV (243 << 16)
+#define KEXEC_ARCH_LOONGARCH (258 << 16)
#define KEXEC_SEGMENT_MAX 16
struct kexec_segment {
const void * buf;
- size_t bufsz;
+ __kernel_size_t bufsz;
const void * mem;
- size_t memsz;
+ __kernel_size_t memsz;
};
#endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index c52ac64..d21e0fc 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -21,7 +21,7 @@
#include <drm/drm.h>
#include <linux/ioctl.h>
#define KFD_IOCTL_MAJOR_VERSION 1
-#define KFD_IOCTL_MINOR_VERSION 6
+#define KFD_IOCTL_MINOR_VERSION 11
struct kfd_ioctl_get_version_args {
__u32 major_version;
__u32 minor_version;
@@ -72,6 +72,11 @@
__u32 queue_id;
__u32 pad;
};
+struct kfd_ioctl_get_available_memory_args {
+ __u64 available;
+ __u32 gpu_id;
+ __u32 pad;
+};
#define KFD_IOC_CACHE_POLICY_COHERENT 0
#define KFD_IOC_CACHE_POLICY_NONCOHERENT 1
struct kfd_ioctl_set_memory_policy_args {
@@ -132,6 +137,7 @@
__u32 gpu_id;
__u32 buf_size_in_bytes;
};
+#define KFD_INVALID_FD 0xffffffff
#define KFD_IOC_EVENT_SIGNAL 0
#define KFD_IOC_EVENT_NODECHANGE 1
#define KFD_IOC_EVENT_DEVICESTATECHANGE 2
@@ -294,12 +300,74 @@
KFD_SMI_EVENT_THERMAL_THROTTLE = 2,
KFD_SMI_EVENT_GPU_PRE_RESET = 3,
KFD_SMI_EVENT_GPU_POST_RESET = 4,
+ KFD_SMI_EVENT_MIGRATE_START = 5,
+ KFD_SMI_EVENT_MIGRATE_END = 6,
+ KFD_SMI_EVENT_PAGE_FAULT_START = 7,
+ KFD_SMI_EVENT_PAGE_FAULT_END = 8,
+ KFD_SMI_EVENT_QUEUE_EVICTION = 9,
+ KFD_SMI_EVENT_QUEUE_RESTORE = 10,
+ KFD_SMI_EVENT_UNMAP_FROM_GPU = 11,
+ KFD_SMI_EVENT_ALL_PROCESS = 64
+};
+enum KFD_MIGRATE_TRIGGERS {
+ KFD_MIGRATE_TRIGGER_PREFETCH,
+ KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU,
+ KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU,
+ KFD_MIGRATE_TRIGGER_TTM_EVICTION
+};
+enum KFD_QUEUE_EVICTION_TRIGGERS {
+ KFD_QUEUE_EVICTION_TRIGGER_SVM,
+ KFD_QUEUE_EVICTION_TRIGGER_USERPTR,
+ KFD_QUEUE_EVICTION_TRIGGER_TTM,
+ KFD_QUEUE_EVICTION_TRIGGER_SUSPEND,
+ KFD_QUEUE_EVICTION_CRIU_CHECKPOINT,
+ KFD_QUEUE_EVICTION_CRIU_RESTORE
+};
+enum KFD_SVM_UNMAP_TRIGGERS {
+ KFD_SVM_UNMAP_TRIGGER_MMU_NOTIFY,
+ KFD_SVM_UNMAP_TRIGGER_MMU_NOTIFY_MIGRATE,
+ KFD_SVM_UNMAP_TRIGGER_UNMAP_FROM_CPU
};
#define KFD_SMI_EVENT_MASK_FROM_INDEX(i) (1ULL << ((i) - 1))
+#define KFD_SMI_EVENT_MSG_SIZE 96
struct kfd_ioctl_smi_events_args {
__u32 gpuid;
__u32 anon_fd;
};
+enum kfd_criu_op {
+ KFD_CRIU_OP_PROCESS_INFO,
+ KFD_CRIU_OP_CHECKPOINT,
+ KFD_CRIU_OP_UNPAUSE,
+ KFD_CRIU_OP_RESTORE,
+ KFD_CRIU_OP_RESUME,
+};
+struct kfd_ioctl_criu_args {
+ __u64 devices;
+ __u64 bos;
+ __u64 priv_data;
+ __u64 priv_data_size;
+ __u32 num_devices;
+ __u32 num_bos;
+ __u32 num_objects;
+ __u32 pid;
+ __u32 op;
+};
+struct kfd_criu_device_bucket {
+ __u32 user_gpu_id;
+ __u32 actual_gpu_id;
+ __u32 drm_fd;
+ __u32 pad;
+};
+struct kfd_criu_bo_bucket {
+ __u64 addr;
+ __u64 size;
+ __u64 offset;
+ __u64 restored_offset;
+ __u32 gpu_id;
+ __u32 alloc_flags;
+ __u32 dmabuf_fd;
+ __u32 pad;
+};
enum kfd_mmio_remap {
KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL = 0,
KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL = 4,
@@ -310,6 +378,7 @@
#define KFD_IOCTL_SVM_FLAG_GPU_RO 0x00000008
#define KFD_IOCTL_SVM_FLAG_GPU_EXEC 0x00000010
#define KFD_IOCTL_SVM_FLAG_GPU_READ_MOSTLY 0x00000020
+#define KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED 0x00000040
enum kfd_ioctl_svm_op {
KFD_IOCTL_SVM_OP_SET_ATTR,
KFD_IOCTL_SVM_OP_GET_ATTR
@@ -337,7 +406,7 @@
__u64 size;
__u32 op;
__u32 nattr;
- struct kfd_ioctl_svm_attribute attrs[0];
+ struct kfd_ioctl_svm_attribute attrs[];
};
struct kfd_ioctl_set_xnack_mode_args {
__s32 xnack_enabled;
@@ -359,10 +428,10 @@
#define AMDKFD_IOC_SET_EVENT AMDKFD_IOW(0x0A, struct kfd_ioctl_set_event_args)
#define AMDKFD_IOC_RESET_EVENT AMDKFD_IOW(0x0B, struct kfd_ioctl_reset_event_args)
#define AMDKFD_IOC_WAIT_EVENTS AMDKFD_IOWR(0x0C, struct kfd_ioctl_wait_events_args)
-#define AMDKFD_IOC_DBG_REGISTER AMDKFD_IOW(0x0D, struct kfd_ioctl_dbg_register_args)
-#define AMDKFD_IOC_DBG_UNREGISTER AMDKFD_IOW(0x0E, struct kfd_ioctl_dbg_unregister_args)
-#define AMDKFD_IOC_DBG_ADDRESS_WATCH AMDKFD_IOW(0x0F, struct kfd_ioctl_dbg_address_watch_args)
-#define AMDKFD_IOC_DBG_WAVE_CONTROL AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args)
+#define AMDKFD_IOC_DBG_REGISTER_DEPRECATED AMDKFD_IOW(0x0D, struct kfd_ioctl_dbg_register_args)
+#define AMDKFD_IOC_DBG_UNREGISTER_DEPRECATED AMDKFD_IOW(0x0E, struct kfd_ioctl_dbg_unregister_args)
+#define AMDKFD_IOC_DBG_ADDRESS_WATCH_DEPRECATED AMDKFD_IOW(0x0F, struct kfd_ioctl_dbg_address_watch_args)
+#define AMDKFD_IOC_DBG_WAVE_CONTROL_DEPRECATED AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args)
#define AMDKFD_IOC_SET_SCRATCH_BACKING_VA AMDKFD_IOWR(0x11, struct kfd_ioctl_set_scratch_backing_va_args)
#define AMDKFD_IOC_GET_TILE_CONFIG AMDKFD_IOWR(0x12, struct kfd_ioctl_get_tile_config_args)
#define AMDKFD_IOC_SET_TRAP_HANDLER AMDKFD_IOW(0x13, struct kfd_ioctl_set_trap_handler_args)
@@ -380,6 +449,8 @@
#define AMDKFD_IOC_SMI_EVENTS AMDKFD_IOWR(0x1F, struct kfd_ioctl_smi_events_args)
#define AMDKFD_IOC_SVM AMDKFD_IOWR(0x20, struct kfd_ioctl_svm_args)
#define AMDKFD_IOC_SET_XNACK_MODE AMDKFD_IOWR(0x21, struct kfd_ioctl_set_xnack_mode_args)
+#define AMDKFD_IOC_CRIU_OP AMDKFD_IOWR(0x22, struct kfd_ioctl_criu_args)
+#define AMDKFD_IOC_AVAILABLE_MEMORY AMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args)
#define AMDKFD_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x22
+#define AMDKFD_COMMAND_END 0x24
#endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 1cf7182..affb6a5 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -216,6 +216,8 @@
#define KVM_EXIT_X86_BUS_LOCK 33
#define KVM_EXIT_XEN 34
#define KVM_EXIT_RISCV_SBI 35
+#define KVM_EXIT_RISCV_CSR 36
+#define KVM_EXIT_NOTIFY 37
#define KVM_INTERNAL_ERROR_EMULATION 1
#define KVM_INTERNAL_ERROR_SIMUL_EX 2
#define KVM_INTERNAL_ERROR_DELIVERY_EV 3
@@ -336,8 +338,15 @@
#define KVM_SYSTEM_EVENT_SHUTDOWN 1
#define KVM_SYSTEM_EVENT_RESET 2
#define KVM_SYSTEM_EVENT_CRASH 3
+#define KVM_SYSTEM_EVENT_WAKEUP 4
+#define KVM_SYSTEM_EVENT_SUSPEND 5
+#define KVM_SYSTEM_EVENT_SEV_TERM 6
__u32 type;
- __u64 flags;
+ __u32 ndata;
+ union {
+ __u64 flags;
+ __u64 data[16];
+ };
} system_event;
struct {
__u64 addr;
@@ -372,6 +381,16 @@
unsigned long args[6];
unsigned long ret[2];
} riscv_sbi;
+ struct {
+ unsigned long csr_num;
+ unsigned long new_value;
+ unsigned long write_mask;
+ unsigned long ret_value;
+ } riscv_csr;
+ struct {
+#define KVM_NOTIFY_CONTEXT_INVALID (1 << 0)
+ __u32 flags;
+ } notify;
char padding[256];
};
#define SYNC_REGS_SIZE_BYTES 2048
@@ -401,7 +420,7 @@
};
struct kvm_coalesced_mmio_ring {
__u32 first, last;
- struct kvm_coalesced_mmio coalesced_mmio[0];
+ struct kvm_coalesced_mmio coalesced_mmio[];
};
#define KVM_COALESCED_MMIO_MAX ((PAGE_SIZE - sizeof(struct kvm_coalesced_mmio_ring)) / sizeof(struct kvm_coalesced_mmio))
struct kvm_translation {
@@ -419,7 +438,10 @@
__u32 op;
__u64 buf;
union {
- __u8 ar;
+ struct {
+ __u8 ar;
+ __u8 key;
+ };
__u32 sida_offset;
__u8 reserved[32];
};
@@ -428,8 +450,11 @@
#define KVM_S390_MEMOP_LOGICAL_WRITE 1
#define KVM_S390_MEMOP_SIDA_READ 2
#define KVM_S390_MEMOP_SIDA_WRITE 3
+#define KVM_S390_MEMOP_ABSOLUTE_READ 4
+#define KVM_S390_MEMOP_ABSOLUTE_WRITE 5
#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
+#define KVM_S390_MEMOP_F_SKEY_PROTECTION (1ULL << 2)
struct kvm_interrupt {
__u32 irq;
};
@@ -452,7 +477,7 @@
};
struct kvm_signal_mask {
__u32 len;
- __u8 sigset[0];
+ __u8 sigset[];
};
struct kvm_tpr_access_ctl {
__u32 enabled;
@@ -472,6 +497,7 @@
#define KVM_MP_STATE_OPERATING 7
#define KVM_MP_STATE_LOAD 8
#define KVM_MP_STATE_AP_RESET_HOLD 9
+#define KVM_MP_STATE_SUSPENDED 10
struct kvm_mp_state {
__u32 mp_state;
};
@@ -890,6 +916,18 @@
#define KVM_CAP_XSAVE2 208
#define KVM_CAP_SYS_ATTRIBUTES 209
#define KVM_CAP_PPC_AIL_MODE_3 210
+#define KVM_CAP_S390_MEM_OP_EXTENSION 211
+#define KVM_CAP_PMU_CAPABILITY 212
+#define KVM_CAP_DISABLE_QUIRKS2 213
+#define KVM_CAP_VM_TSC_CONTROL 214
+#define KVM_CAP_SYSTEM_EVENT_DATA 215
+#define KVM_CAP_ARM_SYSTEM_SUSPEND 216
+#define KVM_CAP_S390_PROTECTED_DUMP 217
+#define KVM_CAP_X86_TRIPLE_FAULT_EVENT 218
+#define KVM_CAP_X86_NOTIFY_VMEXIT 219
+#define KVM_CAP_VM_DISABLE_NX_HUGE_PAGES 220
+#define KVM_CAP_S390_ZPCI_OP 221
+#define KVM_CAP_S390_CPU_TOPOLOGY 222
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
__u32 irqchip;
@@ -943,7 +981,7 @@
struct kvm_irq_routing {
__u32 nr;
__u32 flags;
- struct kvm_irq_routing_entry entries[0];
+ struct kvm_irq_routing_entry entries[];
};
#endif
#ifdef KVM_CAP_MCE
@@ -963,6 +1001,7 @@
#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)
#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3)
#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
+#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
struct kvm_xen_hvm_config {
__u32 flags;
__u32 msr;
@@ -1028,7 +1067,7 @@
#define KVM_REG_SIZE_U2048 0x0080000000000000ULL
struct kvm_reg_list {
__u64 n;
- __u64 reg[0];
+ __u64 reg[];
};
struct kvm_one_reg {
__u64 id;
@@ -1242,6 +1281,48 @@
__u64 size;
__u64 tweak;
};
+enum pv_cmd_dmp_id {
+ KVM_PV_DUMP_INIT,
+ KVM_PV_DUMP_CONFIG_STOR_STATE,
+ KVM_PV_DUMP_COMPLETE,
+ KVM_PV_DUMP_CPU,
+};
+struct kvm_s390_pv_dmp {
+ __u64 subcmd;
+ __u64 buff_addr;
+ __u64 buff_len;
+ __u64 gaddr;
+ __u64 reserved[4];
+};
+enum pv_cmd_info_id {
+ KVM_PV_INFO_VM,
+ KVM_PV_INFO_DUMP,
+};
+struct kvm_s390_pv_info_dump {
+ __u64 dump_cpu_buffer_len;
+ __u64 dump_config_mem_buffer_per_1m;
+ __u64 dump_config_finalize_len;
+};
+struct kvm_s390_pv_info_vm {
+ __u64 inst_calls_list[4];
+ __u64 max_cpus;
+ __u64 max_guests;
+ __u64 max_guest_addr;
+ __u64 feature_indication;
+};
+struct kvm_s390_pv_info_header {
+ __u32 id;
+ __u32 len_max;
+ __u32 len_written;
+ __u32 reserved;
+};
+struct kvm_s390_pv_info {
+ struct kvm_s390_pv_info_header header;
+ union {
+ struct kvm_s390_pv_info_dump dump;
+ struct kvm_s390_pv_info_vm vm;
+ };
+};
enum pv_cmd_id {
KVM_PV_ENABLE,
KVM_PV_DISABLE,
@@ -1250,6 +1331,8 @@
KVM_PV_VERIFY,
KVM_PV_PREP_RESET,
KVM_PV_UNSHARE_ALL,
+ KVM_PV_INFO,
+ KVM_PV_DUMP,
};
struct kvm_pv_cmd {
__u32 cmd;
@@ -1273,14 +1356,38 @@
struct {
__u64 gfn;
} shared_info;
+ struct {
+ __u32 send_port;
+ __u32 type;
+ __u32 flags;
+#define KVM_XEN_EVTCHN_DEASSIGN (1 << 0)
+#define KVM_XEN_EVTCHN_UPDATE (1 << 1)
+#define KVM_XEN_EVTCHN_RESET (1 << 2)
+ union {
+ struct {
+ __u32 port;
+ __u32 vcpu;
+ __u32 priority;
+ } port;
+ struct {
+ __u32 port;
+ __s32 fd;
+ } eventfd;
+ __u32 padding[4];
+ } deliver;
+ } evtchn;
+ __u32 xen_version;
__u64 pad[8];
} u;
};
#define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0
#define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1
#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2
+#define KVM_XEN_ATTR_TYPE_EVTCHN 0x3
+#define KVM_XEN_ATTR_TYPE_XEN_VERSION 0x4
#define KVM_XEN_VCPU_GET_ATTR _IOWR(KVMIO, 0xca, struct kvm_xen_vcpu_attr)
#define KVM_XEN_VCPU_SET_ATTR _IOW(KVMIO, 0xcb, struct kvm_xen_vcpu_attr)
+#define KVM_XEN_HVM_EVTCHN_SEND _IOW(KVMIO, 0xd0, struct kvm_irq_routing_xen_evtchn)
#define KVM_GET_SREGS2 _IOR(KVMIO, 0xcc, struct kvm_sregs2)
#define KVM_SET_SREGS2 _IOW(KVMIO, 0xcd, struct kvm_sregs2)
struct kvm_xen_vcpu_attr {
@@ -1297,6 +1404,13 @@
__u64 time_blocked;
__u64 time_offline;
} runstate;
+ __u32 vcpu_id;
+ struct {
+ __u32 port;
+ __u32 priority;
+ __u64 expires_ns;
+ } timer;
+ __u8 vector;
} u;
};
#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0
@@ -1305,6 +1419,9 @@
#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3
#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4
#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID 0x6
+#define KVM_XEN_VCPU_ATTR_TYPE_TIMER 0x7
+#define KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR 0x8
enum sev_cmd_id {
KVM_SEV_INIT = 0,
KVM_SEV_ES_INIT,
@@ -1480,6 +1597,7 @@
};
#define KVM_BUS_LOCK_DETECTION_OFF (1 << 0)
#define KVM_BUS_LOCK_DETECTION_EXIT (1 << 1)
+#define KVM_PMU_CAP_DISABLE (1 << 0)
struct kvm_stats_header {
__u32 flags;
__u32 name_size;
@@ -1502,7 +1620,8 @@
#define KVM_STATS_UNIT_BYTES (0x1 << KVM_STATS_UNIT_SHIFT)
#define KVM_STATS_UNIT_SECONDS (0x2 << KVM_STATS_UNIT_SHIFT)
#define KVM_STATS_UNIT_CYCLES (0x3 << KVM_STATS_UNIT_SHIFT)
-#define KVM_STATS_UNIT_MAX KVM_STATS_UNIT_CYCLES
+#define KVM_STATS_UNIT_BOOLEAN (0x4 << KVM_STATS_UNIT_SHIFT)
+#define KVM_STATS_UNIT_MAX KVM_STATS_UNIT_BOOLEAN
#define KVM_STATS_BASE_SHIFT 8
#define KVM_STATS_BASE_MASK (0xF << KVM_STATS_BASE_SHIFT)
#define KVM_STATS_BASE_POW10 (0x0 << KVM_STATS_BASE_SHIFT)
@@ -1518,4 +1637,28 @@
};
#define KVM_GET_STATS_FD _IO(KVMIO, 0xce)
#define KVM_GET_XSAVE2 _IOR(KVMIO, 0xcf, struct kvm_xsave)
+#define KVM_S390_PV_CPU_COMMAND _IOWR(KVMIO, 0xd0, struct kvm_pv_cmd)
+#define KVM_X86_NOTIFY_VMEXIT_ENABLED (1ULL << 0)
+#define KVM_X86_NOTIFY_VMEXIT_USER (1ULL << 1)
+#define KVM_S390_ZPCI_OP _IOW(KVMIO, 0xd1, struct kvm_s390_zpci_op)
+struct kvm_s390_zpci_op {
+ __u32 fh;
+ __u8 op;
+ __u8 pad[3];
+ union {
+ struct {
+ __u64 ibv;
+ __u64 sb;
+ __u32 flags;
+ __u32 noi;
+ __u8 isc;
+ __u8 sbo;
+ __u16 pad;
+ } reg_aen;
+ __u64 reserved[8];
+ } u;
+};
+#define KVM_S390_ZPCIOP_REG_AEN 0
+#define KVM_S390_ZPCIOP_DEREG_AEN 1
+#define KVM_S390_ZPCIOP_REGAEN_HOST (1 << 0)
#endif
diff --git a/libc/kernel/uapi/linux/landlock.h b/libc/kernel/uapi/linux/landlock.h
index 50d79d8..ea2fd74 100644
--- a/libc/kernel/uapi/linux/landlock.h
+++ b/libc/kernel/uapi/linux/landlock.h
@@ -43,4 +43,5 @@
#define LANDLOCK_ACCESS_FS_MAKE_FIFO (1ULL << 10)
#define LANDLOCK_ACCESS_FS_MAKE_BLOCK (1ULL << 11)
#define LANDLOCK_ACCESS_FS_MAKE_SYM (1ULL << 12)
+#define LANDLOCK_ACCESS_FS_REFER (1ULL << 13)
#endif
diff --git a/libc/kernel/uapi/linux/lirc.h b/libc/kernel/uapi/linux/lirc.h
index a0ac24a..dff0b63 100644
--- a/libc/kernel/uapi/linux/lirc.h
+++ b/libc/kernel/uapi/linux/lirc.h
@@ -26,18 +26,21 @@
#define LIRC_MODE2_PULSE 0x01000000
#define LIRC_MODE2_FREQUENCY 0x02000000
#define LIRC_MODE2_TIMEOUT 0x03000000
+#define LIRC_MODE2_OVERFLOW 0x04000000
#define LIRC_VALUE_MASK 0x00FFFFFF
#define LIRC_MODE2_MASK 0xFF000000
#define LIRC_SPACE(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_SPACE)
#define LIRC_PULSE(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_PULSE)
#define LIRC_FREQUENCY(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY)
#define LIRC_TIMEOUT(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT)
+#define LIRC_OVERFLOW(val) (((val) & LIRC_VALUE_MASK) | LIRC_MODE2_OVERFLOW)
#define LIRC_VALUE(val) ((val) & LIRC_VALUE_MASK)
#define LIRC_MODE2(val) ((val) & LIRC_MODE2_MASK)
#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE)
#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE)
#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY)
#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT)
+#define LIRC_IS_OVERFLOW(val) (LIRC_MODE2(val) == LIRC_MODE2_OVERFLOW)
#define lirc_t int
#define LIRC_MODE2SEND(x) (x)
#define LIRC_SEND2MODE(x) (x)
@@ -63,17 +66,15 @@
#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE)
#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK)
#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16)
-#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16)
-#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000
#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000
#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000
#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000
-#define LIRC_CAN_SET_REC_FILTER 0x08000000
#define LIRC_CAN_MEASURE_CARRIER 0x02000000
#define LIRC_CAN_USE_WIDEBAND_RECEIVER 0x04000000
#define LIRC_CAN_SEND(x) ((x) & LIRC_CAN_SEND_MASK)
#define LIRC_CAN_REC(x) ((x) & LIRC_CAN_REC_MASK)
-#define LIRC_CAN_NOTIFY_DECODE 0x01000000
+#define LIRC_CAN_SET_REC_FILTER 0
+#define LIRC_CAN_NOTIFY_DECODE 0
#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32)
#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32)
#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32)
diff --git a/libc/kernel/uapi/linux/loadpin.h b/libc/kernel/uapi/linux/loadpin.h
new file mode 100644
index 0000000..2641939
--- /dev/null
+++ b/libc/kernel/uapi/linux/loadpin.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_LOOP_LOADPIN_H
+#define _UAPI_LINUX_LOOP_LOADPIN_H
+#define LOADPIN_IOC_MAGIC 'L'
+#define LOADPIN_IOC_SET_TRUSTED_VERITY_DIGESTS _IOW(LOADPIN_IOC_MAGIC, 0x00, unsigned int)
+#endif
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index 6563411..ac2a0f3 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -99,11 +99,7 @@
#define AAFS_MAGIC 0x5a3c69f0
#define ZONEFS_MAGIC 0x5a4f4653
#define UDF_SUPER_MAGIC 0x15013346
-#define BALLOON_KVM_MAGIC 0x13661366
-#define ZSMALLOC_MAGIC 0x58295829
#define DMA_BUF_MAGIC 0x444d4142
#define DEVMEM_MAGIC 0x454d444d
-#define Z3FOLD_MAGIC 0x33
-#define PPC_CMM_MAGIC 0xc7571590
#define SECRETMEM_MAGIC 0x5345434d
#endif
diff --git a/libc/kernel/uapi/linux/mctp.h b/libc/kernel/uapi/linux/mctp.h
index 21a9a14..f02c12f 100644
--- a/libc/kernel/uapi/linux/mctp.h
+++ b/libc/kernel/uapi/linux/mctp.h
@@ -46,5 +46,13 @@
#define MCTP_ADDR_ANY 0xff
#define MCTP_TAG_MASK 0x07
#define MCTP_TAG_OWNER 0x08
+#define MCTP_TAG_PREALLOC 0x10
#define MCTP_OPT_ADDR_EXT 1
+#define SIOCMCTPALLOCTAG (SIOCPROTOPRIVATE + 0)
+#define SIOCMCTPDROPTAG (SIOCPROTOPRIVATE + 1)
+struct mctp_ioc_tag_ctl {
+ mctp_eid_t peer_addr;
+ __u8 tag;
+ __u16 flags;
+};
#endif
diff --git a/libc/kernel/uapi/linux/mdio.h b/libc/kernel/uapi/linux/mdio.h
index d5c9da8..7a2c9af 100644
--- a/libc/kernel/uapi/linux/mdio.h
+++ b/libc/kernel/uapi/linux/mdio.h
@@ -66,6 +66,19 @@
#define MDIO_PCS_10GBRT_STAT2 33
#define MDIO_AN_10GBT_CTRL 32
#define MDIO_AN_10GBT_STAT 33
+#define MDIO_B10L_PMA_CTRL 2294
+#define MDIO_PMA_10T1L_STAT 2295
+#define MDIO_PCS_10T1L_CTRL 2278
+#define MDIO_PMA_PMD_BT1 18
+#define MDIO_AN_T1_CTRL 512
+#define MDIO_AN_T1_STAT 513
+#define MDIO_AN_T1_ADV_L 514
+#define MDIO_AN_T1_ADV_M 515
+#define MDIO_AN_T1_ADV_H 516
+#define MDIO_AN_T1_LP_L 517
+#define MDIO_AN_T1_LP_M 518
+#define MDIO_AN_T1_LP_H 519
+#define MDIO_PMA_PMD_BT1_CTRL 2100
#define MDIO_PMA_LASI_RXCTRL 0x9000
#define MDIO_PMA_LASI_TXCTRL 0x9001
#define MDIO_PMA_LASI_CTRL 0x9002
@@ -139,6 +152,7 @@
#define MDIO_PMA_CTRL2_10BT 0x000f
#define MDIO_PMA_CTRL2_2_5GBT 0x0030
#define MDIO_PMA_CTRL2_5GBT 0x0031
+#define MDIO_PMA_CTRL2_BASET1 0x003D
#define MDIO_PCS_CTRL2_TYPE 0x0003
#define MDIO_PCS_CTRL2_10GBR 0x0000
#define MDIO_PCS_CTRL2_10GBX 0x0001
@@ -184,6 +198,7 @@
#define MDIO_PMA_EXTABLE_1000BKX 0x0040
#define MDIO_PMA_EXTABLE_100BTX 0x0080
#define MDIO_PMA_EXTABLE_10BT 0x0100
+#define MDIO_PMA_EXTABLE_BT1 0x0800
#define MDIO_PMA_EXTABLE_NBT 0x4000
#define MDIO_PHYXS_LNSTAT_SYNC0 0x0001
#define MDIO_PHYXS_LNSTAT_SYNC1 0x0002
@@ -218,6 +233,44 @@
#define MDIO_AN_10GBT_STAT_LOCOK 0x2000
#define MDIO_AN_10GBT_STAT_MS 0x4000
#define MDIO_AN_10GBT_STAT_MSFLT 0x8000
+#define MDIO_PMA_10T1L_CTRL_LB_EN 0x0001
+#define MDIO_PMA_10T1L_CTRL_EEE_EN 0x0400
+#define MDIO_PMA_10T1L_CTRL_LOW_POWER 0x0800
+#define MDIO_PMA_10T1L_CTRL_2V4_EN 0x1000
+#define MDIO_PMA_10T1L_CTRL_TX_DIS 0x4000
+#define MDIO_PMA_10T1L_CTRL_PMA_RST 0x8000
+#define MDIO_PMA_10T1L_STAT_LINK 0x0001
+#define MDIO_PMA_10T1L_STAT_FAULT 0x0002
+#define MDIO_PMA_10T1L_STAT_POLARITY 0x0004
+#define MDIO_PMA_10T1L_STAT_RECV_FAULT 0x0200
+#define MDIO_PMA_10T1L_STAT_EEE 0x0400
+#define MDIO_PMA_10T1L_STAT_LOW_POWER 0x0800
+#define MDIO_PMA_10T1L_STAT_2V4_ABLE 0x1000
+#define MDIO_PMA_10T1L_STAT_LB_ABLE 0x2000
+#define MDIO_PCS_10T1L_CTRL_LB 0x4000
+#define MDIO_PCS_10T1L_CTRL_RESET 0x8000
+#define MDIO_PMA_PMD_BT1_B10L_ABLE 0x0004
+#define MDIO_AN_T1_ADV_L_PAUSE_CAP ADVERTISE_PAUSE_CAP
+#define MDIO_AN_T1_ADV_L_PAUSE_ASYM ADVERTISE_PAUSE_ASYM
+#define MDIO_AN_T1_ADV_L_FORCE_MS 0x1000
+#define MDIO_AN_T1_ADV_L_REMOTE_FAULT ADVERTISE_RFAULT
+#define MDIO_AN_T1_ADV_L_ACK ADVERTISE_LPACK
+#define MDIO_AN_T1_ADV_L_NEXT_PAGE_REQ ADVERTISE_NPAGE
+#define MDIO_AN_T1_ADV_M_B10L 0x4000
+#define MDIO_AN_T1_ADV_M_MST 0x0010
+#define MDIO_AN_T1_ADV_H_10L_TX_HI_REQ 0x1000
+#define MDIO_AN_T1_ADV_H_10L_TX_HI 0x2000
+#define MDIO_AN_T1_LP_L_PAUSE_CAP LPA_PAUSE_CAP
+#define MDIO_AN_T1_LP_L_PAUSE_ASYM LPA_PAUSE_ASYM
+#define MDIO_AN_T1_LP_L_FORCE_MS 0x1000
+#define MDIO_AN_T1_LP_L_REMOTE_FAULT LPA_RFAULT
+#define MDIO_AN_T1_LP_L_ACK LPA_LPACK
+#define MDIO_AN_T1_LP_L_NEXT_PAGE_REQ LPA_NPAGE
+#define MDIO_AN_T1_LP_M_MST 0x0010
+#define MDIO_AN_T1_LP_M_B10L 0x4000
+#define MDIO_AN_T1_LP_H_10L_TX_HI_REQ 0x1000
+#define MDIO_AN_T1_LP_H_10L_TX_HI 0x2000
+#define MDIO_PMA_PMD_BT1_CTRL_CFG_MST 0x4000
#define MDIO_AN_EEE_ADV_100TX 0x0002
#define MDIO_AN_EEE_ADV_1000T 0x0004
#define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX
diff --git a/libc/kernel/uapi/linux/media-bus-format.h b/libc/kernel/uapi/linux/media-bus-format.h
index 2542a32..4555de1 100644
--- a/libc/kernel/uapi/linux/media-bus-format.h
+++ b/libc/kernel/uapi/linux/media-bus-format.h
@@ -43,9 +43,13 @@
#define MEDIA_BUS_FMT_RGB888_3X8_DELTA 0x101d
#define MEDIA_BUS_FMT_RGB888_1X7X4_SPWG 0x1011
#define MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA 0x1012
+#define MEDIA_BUS_FMT_RGB666_1X30_CPADLO 0x101e
+#define MEDIA_BUS_FMT_RGB888_1X30_CPADLO 0x101f
#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_RGB666_1X36_CPADLO 0x1020
+#define MEDIA_BUS_FMT_RGB888_1X36_CPADLO 0x1021
#define MEDIA_BUS_FMT_RGB121212_1X36 0x1019
#define MEDIA_BUS_FMT_RGB161616_1X48 0x101a
#define MEDIA_BUS_FMT_Y8_1X8 0x2001
diff --git a/libc/kernel/uapi/linux/media.h b/libc/kernel/uapi/linux/media.h
index 5c8efcd..869d47b 100644
--- a/libc/kernel/uapi/linux/media.h
+++ b/libc/kernel/uapi/linux/media.h
@@ -18,7 +18,6 @@
****************************************************************************/
#ifndef __LINUX_MEDIA_H
#define __LINUX_MEDIA_H
-#include <stdint.h>
#include <linux/ioctl.h>
#include <linux/types.h>
struct media_device_info {
@@ -117,6 +116,7 @@
#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28)
#define MEDIA_LNK_FL_DATA_LINK (0 << 28)
#define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28)
+#define MEDIA_LNK_FL_ANCILLARY_LINK (2 << 28)
struct media_link_desc {
struct media_pad_desc source;
struct media_pad_desc sink;
diff --git a/libc/kernel/uapi/linux/minix_fs.h b/libc/kernel/uapi/linux/minix_fs.h
index b6f1c69..0878efe 100644
--- a/libc/kernel/uapi/linux/minix_fs.h
+++ b/libc/kernel/uapi/linux/minix_fs.h
@@ -77,10 +77,10 @@
};
struct minix_dir_entry {
__u16 inode;
- char name[0];
+ char name[];
};
struct minix3_dir_entry {
__u32 inode;
- char name[0];
+ char name[];
};
#endif
diff --git a/libc/kernel/uapi/linux/mmc/ioctl.h b/libc/kernel/uapi/linux/mmc/ioctl.h
index afea6a5..451134b 100644
--- a/libc/kernel/uapi/linux/mmc/ioctl.h
+++ b/libc/kernel/uapi/linux/mmc/ioctl.h
@@ -39,7 +39,7 @@
#define mmc_ioc_cmd_set_data(ic,ptr) ic.data_ptr = (__u64) (unsigned long) ptr
struct mmc_ioc_multi_cmd {
__u64 num_of_cmds;
- struct mmc_ioc_cmd cmds[0];
+ struct mmc_ioc_cmd cmds[];
};
#define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd)
#define MMC_IOC_MULTI_CMD _IOWR(MMC_BLOCK_MAJOR, 1, struct mmc_ioc_multi_cmd)
diff --git a/libc/kernel/uapi/linux/mptcp.h b/libc/kernel/uapi/linux/mptcp.h
index 67b0ce3..da1b5af 100644
--- a/libc/kernel/uapi/linux/mptcp.h
+++ b/libc/kernel/uapi/linux/mptcp.h
@@ -18,12 +18,13 @@
****************************************************************************/
#ifndef _UAPI_MPTCP_H
#define _UAPI_MPTCP_H
+#include <netinet/in.h>
+#include <sys/socket.h>
#include <linux/const.h>
#include <linux/types.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/socket.h>
-#include <sys/socket.h>
#define MPTCP_SUBFLOW_FLAG_MCAP_REM _BITUL(0)
#define MPTCP_SUBFLOW_FLAG_MCAP_LOC _BITUL(1)
#define MPTCP_SUBFLOW_FLAG_JOIN_REM _BITUL(2)
@@ -58,6 +59,9 @@
MPTCP_PM_ATTR_ADDR,
MPTCP_PM_ATTR_RCV_ADD_ADDRS,
MPTCP_PM_ATTR_SUBFLOWS,
+ MPTCP_PM_ATTR_TOKEN,
+ MPTCP_PM_ATTR_LOC_ID,
+ MPTCP_PM_ATTR_ADDR_REMOTE,
__MPTCP_PM_ATTR_MAX
};
#define MPTCP_PM_ATTR_MAX (__MPTCP_PM_ATTR_MAX - 1)
@@ -77,6 +81,7 @@
#define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1)
#define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2)
#define MPTCP_PM_ADDR_FLAG_FULLMESH (1 << 3)
+#define MPTCP_PM_ADDR_FLAG_IMPLICIT (1 << 4)
enum {
MPTCP_PM_CMD_UNSPEC,
MPTCP_PM_CMD_ADD_ADDR,
@@ -86,6 +91,10 @@
MPTCP_PM_CMD_SET_LIMITS,
MPTCP_PM_CMD_GET_LIMITS,
MPTCP_PM_CMD_SET_FLAGS,
+ MPTCP_PM_CMD_ANNOUNCE,
+ MPTCP_PM_CMD_REMOVE,
+ MPTCP_PM_CMD_SUBFLOW_CREATE,
+ MPTCP_PM_CMD_SUBFLOW_DESTROY,
__MPTCP_PM_CMD_AFTER_LAST
};
#define MPTCP_INFO_FLAG_FALLBACK _BITUL(0)
@@ -136,6 +145,7 @@
MPTCP_ATTR_IF_IDX,
MPTCP_ATTR_RESET_REASON,
MPTCP_ATTR_RESET_FLAGS,
+ MPTCP_ATTR_SERVER_SIDE,
__MPTCP_ATTR_AFTER_LAST
};
#define MPTCP_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1)
diff --git a/libc/kernel/uapi/linux/mroute6.h b/libc/kernel/uapi/linux/mroute6.h
index c73765c..68480de 100644
--- a/libc/kernel/uapi/linux/mroute6.h
+++ b/libc/kernel/uapi/linux/mroute6.h
@@ -93,6 +93,7 @@
#define MRT6MSG_NOCACHE 1
#define MRT6MSG_WRONGMIF 2
#define MRT6MSG_WHOLEPKT 3
+#define MRT6MSG_WRMIFWHOLE 4
__u8 im6_mbz;
__u8 im6_msgtype;
__u16 im6_mif;
diff --git a/libc/kernel/uapi/linux/ndctl.h b/libc/kernel/uapi/linux/ndctl.h
index 53f8ba4..f6b9f7f 100644
--- a/libc/kernel/uapi/linux/ndctl.h
+++ b/libc/kernel/uapi/linux/ndctl.h
@@ -32,22 +32,22 @@
__u32 in_offset;
__u32 in_length;
__u32 status;
- __u8 out_buf[0];
+ __u8 out_buf[];
} __packed;
struct nd_cmd_set_config_hdr {
__u32 in_offset;
__u32 in_length;
- __u8 in_buf[0];
+ __u8 in_buf[];
} __packed;
struct nd_cmd_vendor_hdr {
__u32 opcode;
__u32 in_length;
- __u8 in_buf[0];
+ __u8 in_buf[];
} __packed;
struct nd_cmd_vendor_tail {
__u32 status;
__u32 out_length;
- __u8 out_buf[0];
+ __u8 out_buf[];
} __packed;
struct nd_cmd_ars_cap {
__u64 address;
@@ -82,7 +82,7 @@
__u32 reserved;
__u64 err_address;
__u64 length;
- } __packed records[0];
+ } __packed records[];
} __packed;
struct nd_cmd_clear_error {
__u64 address;
@@ -129,7 +129,6 @@
#define ND_DEVICE_REGION_BLK 3
#define ND_DEVICE_NAMESPACE_IO 4
#define ND_DEVICE_NAMESPACE_PMEM 5
-#define ND_DEVICE_NAMESPACE_BLK 6
#define ND_DEVICE_DAX_PMEM 7
enum nd_driver_flags {
ND_DRIVER_DIMM = 1 << ND_DEVICE_DIMM,
@@ -137,7 +136,6 @@
ND_DRIVER_REGION_BLK = 1 << ND_DEVICE_REGION_BLK,
ND_DRIVER_NAMESPACE_IO = 1 << ND_DEVICE_NAMESPACE_IO,
ND_DRIVER_NAMESPACE_PMEM = 1 << ND_DEVICE_NAMESPACE_PMEM,
- ND_DRIVER_NAMESPACE_BLK = 1 << ND_DEVICE_NAMESPACE_BLK,
ND_DRIVER_DAX_PMEM = 1 << ND_DEVICE_DAX_PMEM,
};
enum ars_masks {
diff --git a/libc/kernel/uapi/linux/neighbour.h b/libc/kernel/uapi/linux/neighbour.h
index 278f7d1..b86d2ae 100644
--- a/libc/kernel/uapi/linux/neighbour.h
+++ b/libc/kernel/uapi/linux/neighbour.h
@@ -46,6 +46,8 @@
NDA_NH_ID,
NDA_FDB_EXT_ATTRS,
NDA_FLAGS_EXT,
+ NDA_NDM_STATE_MASK,
+ NDA_NDM_FLAGS_MASK,
__NDA_MAX
};
#define NDA_MAX (__NDA_MAX - 1)
@@ -106,6 +108,7 @@
NDTPA_QUEUE_LENBYTES,
NDTPA_MCAST_REPROBES,
NDTPA_PAD,
+ NDTPA_INTERVAL_PROBE_TIME_MS,
__NDTPA_MAX
};
#define NDTPA_MAX (__NDTPA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/net_dropmon.h b/libc/kernel/uapi/linux/net_dropmon.h
index 01b76cb..4d2c336 100644
--- a/libc/kernel/uapi/linux/net_dropmon.h
+++ b/libc/kernel/uapi/linux/net_dropmon.h
@@ -36,11 +36,11 @@
};
struct net_dm_config_msg {
__u32 entries;
- struct net_dm_config_entry options[0];
+ struct net_dm_config_entry options[];
};
struct net_dm_alert_msg {
__u32 entries;
- struct net_dm_drop_point points[0];
+ struct net_dm_drop_point points[];
};
struct net_dm_user_msg {
union {
@@ -87,6 +87,7 @@
NET_DM_ATTR_SW_DROPS,
NET_DM_ATTR_HW_DROPS,
NET_DM_ATTR_FLOW_ACTION_COOKIE,
+ NET_DM_ATTR_REASON,
__NET_DM_ATTR_MAX,
NET_DM_ATTR_MAX = __NET_DM_ATTR_MAX - 1
};
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
index 75fa359..d100dec 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
@@ -70,6 +70,7 @@
NFQA_SECCTX,
NFQA_VLAN,
NFQA_L2HDR,
+ NFQA_PRIORITY,
__NFQA_MAX
};
#define NFQA_MAX (__NFQA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/netfilter/x_tables.h b/libc/kernel/uapi/linux/netfilter/x_tables.h
index 46bde57..0993265 100644
--- a/libc/kernel/uapi/linux/netfilter/x_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/x_tables.h
@@ -36,7 +36,7 @@
} kernel;
__u16 match_size;
} u;
- unsigned char data[0];
+ unsigned char data[];
};
struct xt_entry_target {
union {
@@ -87,7 +87,7 @@
struct xt_counters_info {
char name[XT_TABLE_MAXNAMELEN];
unsigned int num_counters;
- struct xt_counters counters[0];
+ struct xt_counters counters[];
};
#define XT_INV_PROTO 0x40
#define XT_MATCH_ITERATE(type,e,fn,args...) \
diff --git a/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h b/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h
index 340625f..862f514 100644
--- a/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h
+++ b/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h
@@ -72,7 +72,7 @@
__u16 next_offset;
unsigned int comefrom;
struct xt_counters counters;
- unsigned char elems[0];
+ unsigned char elems[];
};
#define ARPT_BASE_CTL 96
#define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL)
@@ -99,11 +99,11 @@
unsigned int underflow[NF_ARP_NUMHOOKS];
unsigned int num_counters;
struct xt_counters __user * counters;
- struct arpt_entry entries[0];
+ struct arpt_entry entries[];
};
struct arpt_get_entries {
char name[XT_TABLE_MAXNAMELEN];
unsigned int size;
- struct arpt_entry entrytable[0];
+ struct arpt_entry entrytable[];
};
#endif
diff --git a/libc/kernel/uapi/linux/netfilter_bridge/ebt_among.h b/libc/kernel/uapi/linux/netfilter_bridge/ebt_among.h
index 74cd550..aa39c5b 100644
--- a/libc/kernel/uapi/linux/netfilter_bridge/ebt_among.h
+++ b/libc/kernel/uapi/linux/netfilter_bridge/ebt_among.h
@@ -28,7 +28,7 @@
struct ebt_mac_wormhash {
int table[257];
int poolsize;
- struct ebt_mac_wormhash_tuple pool[0];
+ struct ebt_mac_wormhash_tuple pool[];
};
#define ebt_mac_wormhash_size(x) ((x) ? sizeof(struct ebt_mac_wormhash) + (x)->poolsize * sizeof(struct ebt_mac_wormhash_tuple) : 0)
struct ebt_among_info {
diff --git a/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h b/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h
index 033c519..14a65ad 100644
--- a/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h
+++ b/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h
@@ -79,7 +79,7 @@
__u16 next_offset;
unsigned int comefrom;
struct xt_counters counters;
- unsigned char elems[0];
+ unsigned char elems[];
};
#define IPT_BASE_CTL 64
#define IPT_SO_SET_REPLACE (IPT_BASE_CTL)
@@ -113,12 +113,12 @@
unsigned int underflow[NF_INET_NUMHOOKS];
unsigned int num_counters;
struct xt_counters __user * counters;
- struct ipt_entry entries[0];
+ struct ipt_entry entries[];
};
struct ipt_get_entries {
char name[XT_TABLE_MAXNAMELEN];
unsigned int size;
- struct ipt_entry entrytable[0];
+ struct ipt_entry entrytable[];
};
static __inline__ struct xt_entry_target * ipt_get_target(struct ipt_entry * e) {
return(struct xt_entry_target *) ((char *) e + e->target_offset);
diff --git a/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h b/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h
index b3f426d..22071db 100644
--- a/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h
+++ b/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h
@@ -133,12 +133,12 @@
unsigned int underflow[NF_INET_NUMHOOKS];
unsigned int num_counters;
struct xt_counters __user * counters;
- struct ip6t_entry entries[0];
+ struct ip6t_entry entries[];
};
struct ip6t_get_entries {
char name[XT_TABLE_MAXNAMELEN];
unsigned int size;
- struct ip6t_entry entrytable[0];
+ struct ip6t_entry entrytable[];
};
static __inline__ struct xt_entry_target * ip6t_get_target(struct ip6t_entry * e) {
return(struct xt_entry_target *) ((char *) e + e->target_offset);
diff --git a/libc/kernel/uapi/linux/netlink.h b/libc/kernel/uapi/linux/netlink.h
index 77825cc..bc3e749 100644
--- a/libc/kernel/uapi/linux/netlink.h
+++ b/libc/kernel/uapi/linux/netlink.h
@@ -73,6 +73,7 @@
#define NLM_F_CREATE 0x400
#define NLM_F_APPEND 0x800
#define NLM_F_NONREC 0x100
+#define NLM_F_BULK 0x200
#define NLM_F_CAPPED 0x100
#define NLM_F_ACK_TLVS 0x200
#define NLMSG_ALIGNTO 4U
diff --git a/libc/kernel/uapi/linux/nfs4.h b/libc/kernel/uapi/linux/nfs4.h
index 9d614ce..ef860e2 100644
--- a/libc/kernel/uapi/linux/nfs4.h
+++ b/libc/kernel/uapi/linux/nfs4.h
@@ -45,6 +45,7 @@
#define NFS4_FH_VOL_RENAME 0x0008
#define NFS4_OPEN_RESULT_CONFIRM 0x0002
#define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004
+#define NFS4_OPEN_RESULT_PRESERVE_UNLINKED 0x0008
#define NFS4_OPEN_RESULT_MAY_NOTIFY_LOCK 0x0020
#define NFS4_SHARE_ACCESS_MASK 0x000F
#define NFS4_SHARE_ACCESS_READ 0x0001
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index e902178..c3aefa3 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -185,6 +185,11 @@
NL80211_CMD_COLOR_CHANGE_COMPLETED,
NL80211_CMD_SET_FILS_AAD,
NL80211_CMD_ASSOC_COMEBACK,
+ NL80211_CMD_ADD_LINK,
+ NL80211_CMD_REMOVE_LINK,
+ NL80211_CMD_ADD_LINK_STA,
+ NL80211_CMD_MODIFY_LINK_STA,
+ NL80211_CMD_REMOVE_LINK_STA,
__NL80211_CMD_AFTER_LAST,
NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
};
@@ -511,6 +516,17 @@
NL80211_ATTR_MBSSID_ELEMS,
NL80211_ATTR_RADAR_BACKGROUND,
NL80211_ATTR_AP_SETTINGS_FLAGS,
+ NL80211_ATTR_EHT_CAPABILITY,
+ NL80211_ATTR_DISABLE_EHT,
+ NL80211_ATTR_MLO_LINKS,
+ NL80211_ATTR_MLO_LINK_ID,
+ NL80211_ATTR_MLD_ADDR,
+ NL80211_ATTR_MLO_SUPPORT,
+ NL80211_ATTR_MAX_NUM_AKM_SUITES,
+ NL80211_ATTR_EML_CAPABILITY,
+ NL80211_ATTR_MLD_CAPA_AND_OPS,
+ NL80211_ATTR_TX_HW_TIMESTAMP,
+ NL80211_ATTR_RX_HW_TIMESTAMP,
__NL80211_ATTR_AFTER_LAST,
NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -555,6 +571,8 @@
#define NL80211_HE_MAX_CAPABILITY_LEN 54
#define NL80211_MAX_NR_CIPHER_SUITES 5
#define NL80211_MAX_NR_AKM_SUITES 2
+#define NL80211_EHT_MIN_CAPABILITY_LEN 13
+#define NL80211_EHT_MAX_CAPABILITY_LEN 51
#define NL80211_MIN_REMAIN_ON_CHANNEL_TIME 10
#define NL80211_SCAN_RSSI_THOLD_OFF - 300
#define NL80211_CQM_TXE_MAX_INTVL 1800
@@ -616,6 +634,29 @@
NL80211_RATE_INFO_HE_RU_ALLOC_996,
NL80211_RATE_INFO_HE_RU_ALLOC_2x996,
};
+enum nl80211_eht_gi {
+ NL80211_RATE_INFO_EHT_GI_0_8,
+ NL80211_RATE_INFO_EHT_GI_1_6,
+ NL80211_RATE_INFO_EHT_GI_3_2,
+};
+enum nl80211_eht_ru_alloc {
+ NL80211_RATE_INFO_EHT_RU_ALLOC_26,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_52,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_52P26,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_106,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_106P26,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_242,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_484P242,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996P484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_2x996,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_3x996,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484,
+ NL80211_RATE_INFO_EHT_RU_ALLOC_4x996,
+};
enum nl80211_rate_info {
__NL80211_RATE_INFO_INVALID,
NL80211_RATE_INFO_BITRATE,
@@ -635,6 +676,11 @@
NL80211_RATE_INFO_HE_GI,
NL80211_RATE_INFO_HE_DCM,
NL80211_RATE_INFO_HE_RU_ALLOC,
+ NL80211_RATE_INFO_320_MHZ_WIDTH,
+ NL80211_RATE_INFO_EHT_MCS,
+ NL80211_RATE_INFO_EHT_NSS,
+ NL80211_RATE_INFO_EHT_GI,
+ NL80211_RATE_INFO_EHT_RU_ALLOC,
__NL80211_RATE_INFO_AFTER_LAST,
NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1
};
@@ -754,6 +800,10 @@
NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE,
__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
NL80211_BAND_IFTYPE_ATTR_MAX = __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST - 1
};
@@ -810,6 +860,8 @@
NL80211_FREQUENCY_ATTR_4MHZ,
NL80211_FREQUENCY_ATTR_8MHZ,
NL80211_FREQUENCY_ATTR_16MHZ,
+ NL80211_FREQUENCY_ATTR_NO_320MHZ,
+ NL80211_FREQUENCY_ATTR_NO_EHT,
__NL80211_FREQUENCY_ATTR_AFTER_LAST,
NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
};
@@ -878,6 +930,7 @@
NL80211_RRF_NO_80MHZ = 1 << 15,
NL80211_RRF_NO_160MHZ = 1 << 16,
NL80211_RRF_NO_HE = 1 << 17,
+ NL80211_RRF_NO_320MHZ = 1 << 18,
};
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
#define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR
@@ -1033,6 +1086,7 @@
NL80211_CHAN_WIDTH_4,
NL80211_CHAN_WIDTH_8,
NL80211_CHAN_WIDTH_16,
+ NL80211_CHAN_WIDTH_320,
};
enum nl80211_bss_scan_width {
NL80211_BSS_CHAN_WIDTH_20,
@@ -1063,6 +1117,7 @@
NL80211_BSS_PARENT_BSSID,
NL80211_BSS_CHAIN_SIGNAL,
NL80211_BSS_FREQUENCY_OFFSET,
+ NL80211_BSS_MLO_LINK_ID,
__NL80211_BSS_AFTER_LAST,
NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1
};
diff --git a/libc/kernel/uapi/linux/nvme_ioctl.h b/libc/kernel/uapi/linux/nvme_ioctl.h
index f2a328e..388e83f 100644
--- a/libc/kernel/uapi/linux/nvme_ioctl.h
+++ b/libc/kernel/uapi/linux/nvme_ioctl.h
@@ -63,7 +63,10 @@
__u64 metadata;
__u64 addr;
__u32 metadata_len;
- __u32 data_len;
+ union {
+ __u32 data_len;
+ __u32 vec_cnt;
+ };
__u32 cdw10;
__u32 cdw11;
__u32 cdw12;
@@ -74,6 +77,26 @@
__u32 rsvd2;
__u64 result;
};
+struct nvme_uring_cmd {
+ __u8 opcode;
+ __u8 flags;
+ __u16 rsvd1;
+ __u32 nsid;
+ __u32 cdw2;
+ __u32 cdw3;
+ __u64 metadata;
+ __u64 addr;
+ __u32 metadata_len;
+ __u32 data_len;
+ __u32 cdw10;
+ __u32 cdw11;
+ __u32 cdw12;
+ __u32 cdw13;
+ __u32 cdw14;
+ __u32 cdw15;
+ __u32 timeout_ms;
+ __u32 rsvd2;
+};
#define nvme_admin_cmd nvme_passthru_cmd
#define NVME_IOCTL_ID _IO('N', 0x40)
#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd)
@@ -84,4 +107,9 @@
#define NVME_IOCTL_RESCAN _IO('N', 0x46)
#define NVME_IOCTL_ADMIN64_CMD _IOWR('N', 0x47, struct nvme_passthru_cmd64)
#define NVME_IOCTL_IO64_CMD _IOWR('N', 0x48, struct nvme_passthru_cmd64)
+#define NVME_IOCTL_IO64_CMD_VEC _IOWR('N', 0x49, struct nvme_passthru_cmd64)
+#define NVME_URING_CMD_IO _IOWR('N', 0x80, struct nvme_uring_cmd)
+#define NVME_URING_CMD_IO_VEC _IOWR('N', 0x81, struct nvme_uring_cmd)
+#define NVME_URING_CMD_ADMIN _IOWR('N', 0x82, struct nvme_uring_cmd)
+#define NVME_URING_CMD_ADMIN_VEC _IOWR('N', 0x83, struct nvme_uring_cmd)
#endif
diff --git a/libc/kernel/uapi/linux/omap3isp.h b/libc/kernel/uapi/linux/omap3isp.h
index d2eceb7..53345e3 100644
--- a/libc/kernel/uapi/linux/omap3isp.h
+++ b/libc/kernel/uapi/linux/omap3isp.h
@@ -89,10 +89,11 @@
struct omap3isp_stat_data {
struct timeval ts;
void __user * buf;
- __u32 buf_size;
+ __struct_group(, frame,, __u32 buf_size;
__u16 frame_number;
__u16 cur_frame;
__u16 config_counter;
+ );
};
#define OMAP3ISP_HIST_BINS_32 0
#define OMAP3ISP_HIST_BINS_64 1
diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h
index 1f8ae17..c7d719c 100644
--- a/libc/kernel/uapi/linux/openvswitch.h
+++ b/libc/kernel/uapi/linux/openvswitch.h
@@ -190,6 +190,10 @@
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4,
OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6,
OVS_KEY_ATTR_NSH,
+ OVS_KEY_ATTR_PACKET_TYPE,
+ OVS_KEY_ATTR_ND_EXTENSIONS,
+ OVS_KEY_ATTR_TUNNEL_INFO,
+ OVS_KEY_ATTR_IPV6_EXTHDRS,
__OVS_KEY_ATTR_MAX
};
#define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1)
@@ -245,6 +249,9 @@
__u8 ipv6_hlimit;
__u8 ipv6_frag;
};
+struct ovs_key_ipv6_exthdrs {
+ __u16 hdrs;
+};
struct ovs_key_tcp {
__be16 tcp_src;
__be16 tcp_dst;
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index 46612da..87549aa 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -525,6 +525,7 @@
#define PCI_EXP_SLTCTL_PWR_OFF 0x0400
#define PCI_EXP_SLTCTL_EIC 0x0800
#define PCI_EXP_SLTCTL_DLLSCE 0x1000
+#define PCI_EXP_SLTCTL_ASPL_DISABLE 0x2000
#define PCI_EXP_SLTCTL_IBPD_DISABLE 0x4000
#define PCI_EXP_SLTSTA 0x1a
#define PCI_EXP_SLTSTA_ABP 0x0001
@@ -634,7 +635,8 @@
#define PCI_EXT_CAP_ID_DVSEC 0x23
#define PCI_EXT_CAP_ID_DLF 0x25
#define PCI_EXT_CAP_ID_PL_16GT 0x26
-#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_16GT
+#define PCI_EXT_CAP_ID_DOE 0x2E
+#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE
#define PCI_EXT_CAP_DSN_SIZEOF 12
#define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40
#define PCI_ERR_UNCOR_STATUS 0x04
@@ -937,4 +939,25 @@
#define PCI_PL_16GT_LE_CTRL_DSP_TX_PRESET_MASK 0x0000000F
#define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_MASK 0x000000F0
#define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_SHIFT 4
+#define PCI_DOE_CAP 0x04
+#define PCI_DOE_CAP_INT_SUP 0x00000001
+#define PCI_DOE_CAP_INT_MSG_NUM 0x00000ffe
+#define PCI_DOE_CTRL 0x08
+#define PCI_DOE_CTRL_ABORT 0x00000001
+#define PCI_DOE_CTRL_INT_EN 0x00000002
+#define PCI_DOE_CTRL_GO 0x80000000
+#define PCI_DOE_STATUS 0x0c
+#define PCI_DOE_STATUS_BUSY 0x00000001
+#define PCI_DOE_STATUS_INT_STATUS 0x00000002
+#define PCI_DOE_STATUS_ERROR 0x00000004
+#define PCI_DOE_STATUS_DATA_OBJECT_READY 0x80000000
+#define PCI_DOE_WRITE 0x10
+#define PCI_DOE_READ 0x14
+#define PCI_DOE_DATA_OBJECT_HEADER_1_VID 0x0000ffff
+#define PCI_DOE_DATA_OBJECT_HEADER_1_TYPE 0x00ff0000
+#define PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH 0x0003ffff
+#define PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX 0x000000ff
+#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID 0x0000ffff
+#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL 0x00ff0000
+#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_NEXT_INDEX 0xff000000
#endif
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index b022586..165ff45 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -165,6 +165,8 @@
PERF_BR_SYSRET = 8,
PERF_BR_COND_CALL = 9,
PERF_BR_COND_RET = 10,
+ PERF_BR_ERET = 11,
+ PERF_BR_IRQ = 12,
PERF_BR_MAX,
};
#define PERF_SAMPLE_BRANCH_PLM_ALL (PERF_SAMPLE_BRANCH_USER | PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_HV)
@@ -191,7 +193,8 @@
PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
PERF_FORMAT_ID = 1U << 2,
PERF_FORMAT_GROUP = 1U << 3,
- PERF_FORMAT_MAX = 1U << 4,
+ PERF_FORMAT_LOST = 1U << 4,
+ PERF_FORMAT_MAX = 1U << 5,
};
#define PERF_ATTR_SIZE_VER0 64
#define PERF_ATTR_SIZE_VER1 72
@@ -244,7 +247,7 @@
struct perf_event_query_bpf {
__u32 ids_len;
__u32 prog_cnt;
- __u32 ids[0];
+ __u32 ids[];
};
#define PERF_EVENT_IOC_ENABLE _IO('$', 0)
#define PERF_EVENT_IOC_DISABLE _IO('$', 1)
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index 9fd89e0..580e83e 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -199,7 +199,7 @@
short offoff;
short hoff;
__be32 hmask;
- struct tc_u32_key keys[0];
+ struct tc_u32_key keys[];
};
struct tc_u32_mark {
__u32 val;
@@ -209,7 +209,7 @@
struct tc_u32_pcnt {
__u64 rcnt;
__u64 rhit;
- __u64 kcnts[0];
+ __u64 kcnts[];
};
#define TC_U32_TERMINAL 1
#define TC_U32_OFFSET 2
@@ -459,6 +459,9 @@
TCA_FLOWER_KEY_MPLS_OPTS,
TCA_FLOWER_KEY_HASH,
TCA_FLOWER_KEY_HASH_MASK,
+ TCA_FLOWER_KEY_NUM_OF_VLANS,
+ TCA_FLOWER_KEY_PPPOE_SID,
+ TCA_FLOWER_KEY_PPP_PROTO,
__TCA_FLOWER_MAX,
};
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
@@ -476,6 +479,7 @@
TCA_FLOWER_KEY_ENC_OPTS_GENEVE,
TCA_FLOWER_KEY_ENC_OPTS_VXLAN,
TCA_FLOWER_KEY_ENC_OPTS_ERSPAN,
+ TCA_FLOWER_KEY_ENC_OPTS_GTP,
__TCA_FLOWER_KEY_ENC_OPTS_MAX,
};
#define TCA_FLOWER_KEY_ENC_OPTS_MAX (__TCA_FLOWER_KEY_ENC_OPTS_MAX - 1)
@@ -503,6 +507,13 @@
};
#define TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX (__TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX - 1)
enum {
+ TCA_FLOWER_KEY_ENC_OPT_GTP_UNSPEC,
+ TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE,
+ TCA_FLOWER_KEY_ENC_OPT_GTP_QFI,
+ __TCA_FLOWER_KEY_ENC_OPT_GTP_MAX,
+};
+#define TCA_FLOWER_KEY_ENC_OPT_GTP_MAX (__TCA_FLOWER_KEY_ENC_OPT_GTP_MAX - 1)
+enum {
TCA_FLOWER_KEY_MPLS_OPTS_UNSPEC,
TCA_FLOWER_KEY_MPLS_OPTS_LSE,
__TCA_FLOWER_KEY_MPLS_OPTS_MAX,
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 9b4c695..1dac726 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -179,6 +179,11 @@
#define PR_SCHED_CORE_SCOPE_THREAD 0
#define PR_SCHED_CORE_SCOPE_THREAD_GROUP 1
#define PR_SCHED_CORE_SCOPE_PROCESS_GROUP 2
+#define PR_SME_SET_VL 63
+#define PR_SME_SET_VL_ONEXEC (1 << 18)
+#define PR_SME_GET_VL 64
+#define PR_SME_VL_LEN_MASK 0xffff
+#define PR_SME_VL_INHERIT (1 << 17)
#define PR_SET_VMA 0x53564d41
#define PR_SET_VMA_ANON_NAME 0
#endif
diff --git a/libc/kernel/uapi/linux/psci.h b/libc/kernel/uapi/linux/psci.h
index bc522e7..31e7465 100644
--- a/libc/kernel/uapi/linux/psci.h
+++ b/libc/kernel/uapi/linux/psci.h
@@ -60,6 +60,8 @@
#define PSCI_0_2_TOS_UP_MIGRATE 0
#define PSCI_0_2_TOS_UP_NO_MIGRATE 1
#define PSCI_0_2_TOS_MP 2
+#define PSCI_1_1_RESET_TYPE_SYSTEM_WARM_RESET 0
+#define PSCI_1_1_RESET_TYPE_VENDOR_START 0x80000000U
#define PSCI_VERSION_MAJOR_SHIFT 16
#define PSCI_VERSION_MINOR_MASK ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1)
#define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK
diff --git a/libc/kernel/uapi/linux/raid/md_p.h b/libc/kernel/uapi/linux/raid/md_p.h
index 4ad444a..dc3084a 100644
--- a/libc/kernel/uapi/linux/raid/md_p.h
+++ b/libc/kernel/uapi/linux/raid/md_p.h
@@ -168,7 +168,7 @@
__le32 sb_csum;
__le32 max_dev;
__u8 pad3[64 - 32];
- __le16 dev_roles[0];
+ __le16 dev_roles[];
};
#define MD_FEATURE_BITMAP_OFFSET 1
#define MD_FEATURE_RECOVERY_OFFSET 2
diff --git a/libc/kernel/uapi/linux/random.h b/libc/kernel/uapi/linux/random.h
index 2d3cfef..8df411b 100644
--- a/libc/kernel/uapi/linux/random.h
+++ b/libc/kernel/uapi/linux/random.h
@@ -31,7 +31,7 @@
struct rand_pool_info {
int entropy_count;
int buf_size;
- __u32 buf[0];
+ __u32 buf[];
};
#define GRND_NONBLOCK 0x0001
#define GRND_RANDOM 0x0002
diff --git a/libc/kernel/uapi/linux/reiserfs_xattr.h b/libc/kernel/uapi/linux/reiserfs_xattr.h
index 36d31f6..16a7a08 100644
--- a/libc/kernel/uapi/linux/reiserfs_xattr.h
+++ b/libc/kernel/uapi/linux/reiserfs_xattr.h
@@ -27,6 +27,6 @@
struct reiserfs_security_handle {
const char * name;
void * value;
- size_t length;
+ __kernel_size_t length;
};
#endif
diff --git a/libc/kernel/uapi/linux/rfkill.h b/libc/kernel/uapi/linux/rfkill.h
index 6020baf..b90e67c 100644
--- a/libc/kernel/uapi/linux/rfkill.h
+++ b/libc/kernel/uapi/linux/rfkill.h
@@ -63,4 +63,6 @@
#define RFKILL_IOC_MAGIC 'R'
#define RFKILL_IOC_NOINPUT 1
#define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT)
+#define RFKILL_IOC_MAX_SIZE 2
+#define RFKILL_IOCTL_MAX_SIZE _IOW(RFKILL_IOC_MAGIC, RFKILL_IOC_MAX_SIZE, __u32)
#endif
diff --git a/libc/kernel/uapi/linux/romfs_fs.h b/libc/kernel/uapi/linux/romfs_fs.h
index 8e98714..bffbaf9 100644
--- a/libc/kernel/uapi/linux/romfs_fs.h
+++ b/libc/kernel/uapi/linux/romfs_fs.h
@@ -35,14 +35,14 @@
__be32 word1;
__be32 size;
__be32 checksum;
- char name[0];
+ char name[];
};
struct romfs_inode {
__be32 next;
__be32 spec;
__be32 size;
__be32 checksum;
- char name[0];
+ char name[];
};
#define ROMFH_TYPE 7
#define ROMFH_HRD 0
diff --git a/libc/kernel/uapi/linux/rpmsg.h b/libc/kernel/uapi/linux/rpmsg.h
index c5b5a76..9ceccdd 100644
--- a/libc/kernel/uapi/linux/rpmsg.h
+++ b/libc/kernel/uapi/linux/rpmsg.h
@@ -28,4 +28,6 @@
};
#define RPMSG_CREATE_EPT_IOCTL _IOW(0xb5, 0x1, struct rpmsg_endpoint_info)
#define RPMSG_DESTROY_EPT_IOCTL _IO(0xb5, 0x2)
+#define RPMSG_CREATE_DEV_IOCTL _IOW(0xb5, 0x3, struct rpmsg_endpoint_info)
+#define RPMSG_RELEASE_DEV_IOCTL _IOW(0xb5, 0x4, struct rpmsg_endpoint_info)
#endif
diff --git a/libc/kernel/uapi/linux/rseq.h b/libc/kernel/uapi/linux/rseq.h
index ba0ceb1..29a9457 100644
--- a/libc/kernel/uapi/linux/rseq.h
+++ b/libc/kernel/uapi/linux/rseq.h
@@ -47,22 +47,7 @@
struct rseq {
__u32 cpu_id_start;
__u32 cpu_id;
- union {
- __u64 ptr64;
-#ifdef __LP64__
- __u64 ptr;
-#else
- struct {
-#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || defined(__BIG_ENDIAN)
- __u32 padding;
- __u32 ptr32;
-#else
- __u32 ptr32;
- __u32 padding;
-#endif
- } ptr;
-#endif
- } rseq_cs;
+ __u64 rseq_cs;
__u32 flags;
} __attribute__((aligned(4 * sizeof(__u64))));
#endif
diff --git a/libc/kernel/uapi/linux/rtc.h b/libc/kernel/uapi/linux/rtc.h
index cf5f22a..d75bc45 100644
--- a/libc/kernel/uapi/linux/rtc.h
+++ b/libc/kernel/uapi/linux/rtc.h
@@ -96,7 +96,8 @@
#define RTC_FEATURE_UPDATE_INTERRUPT 4
#define RTC_FEATURE_CORRECTION 5
#define RTC_FEATURE_BACKUP_SWITCH_MODE 6
-#define RTC_FEATURE_CNT 7
+#define RTC_FEATURE_ALARM_WAKEUP_ONLY 7
+#define RTC_FEATURE_CNT 8
#define RTC_PARAM_FEATURES 0
#define RTC_PARAM_CORRECTION 1
#define RTC_PARAM_BACKUP_SWITCH_MODE 2
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index 91c3ee4..7201827 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -131,6 +131,8 @@
#define RTM_NEWSTATS RTM_NEWSTATS
RTM_GETSTATS = 94,
#define RTM_GETSTATS RTM_GETSTATS
+ RTM_SETSTATS,
+#define RTM_SETSTATS RTM_SETSTATS
RTM_NEWCACHEREPORT = 96,
#define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
RTM_NEWCHAIN = 100,
@@ -163,6 +165,12 @@
#define RTM_DELNEXTHOPBUCKET RTM_DELNEXTHOPBUCKET
RTM_GETNEXTHOPBUCKET,
#define RTM_GETNEXTHOPBUCKET RTM_GETNEXTHOPBUCKET
+ RTM_NEWTUNNEL = 120,
+#define RTM_NEWTUNNEL RTM_NEWTUNNEL
+ RTM_DELTUNNEL,
+#define RTM_DELTUNNEL RTM_DELTUNNEL
+ RTM_GETTUNNEL,
+#define RTM_GETTUNNEL RTM_GETTUNNEL
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
@@ -315,7 +323,7 @@
#define RTNH_DATA(rtnh) ((struct rtattr *) (((char *) (rtnh)) + RTNH_LENGTH(0)))
struct rtvia {
__kernel_sa_family_t rtvia_family;
- __u8 rtvia_addr[0];
+ __u8 rtvia_addr[];
};
struct rta_cacheinfo {
__u32 rta_clntref;
@@ -561,6 +569,10 @@
#define RTNLGRP_BRVLAN RTNLGRP_BRVLAN
RTNLGRP_MCTP_IFADDR,
#define RTNLGRP_MCTP_IFADDR RTNLGRP_MCTP_IFADDR
+ RTNLGRP_TUNNEL,
+#define RTNLGRP_TUNNEL RTNLGRP_TUNNEL
+ RTNLGRP_STATS,
+#define RTNLGRP_STATS RTNLGRP_STATS
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
@@ -592,4 +604,5 @@
#define RTEXT_FILTER_MRP (1 << 4)
#define RTEXT_FILTER_CFM_CONFIG (1 << 5)
#define RTEXT_FILTER_CFM_STATUS (1 << 6)
+#define RTEXT_FILTER_MST (1 << 7)
#endif
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index 765d6c9..4bf2412 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -210,7 +210,7 @@
__u16 sac_outbound_streams;
__u16 sac_inbound_streams;
sctp_assoc_t sac_assoc_id;
- __u8 sac_info[0];
+ __u8 sac_info[];
};
enum sctp_sac_state {
SCTP_COMM_UP,
@@ -244,7 +244,7 @@
__u32 sre_length;
__be16 sre_error;
sctp_assoc_t sre_assoc_id;
- __u8 sre_data[0];
+ __u8 sre_data[];
};
struct sctp_send_failed {
__u16 ssf_type;
@@ -253,7 +253,7 @@
__u32 ssf_error;
struct sctp_sndrcvinfo ssf_info;
sctp_assoc_t ssf_assoc_id;
- __u8 ssf_data[0];
+ __u8 ssf_data[];
};
struct sctp_send_failed_event {
__u16 ssf_type;
@@ -262,7 +262,7 @@
__u32 ssf_error;
struct sctp_sndinfo ssfe_info;
sctp_assoc_t ssf_assoc_id;
- __u8 ssf_data[0];
+ __u8 ssf_data[];
};
enum sctp_ssf_flags {
SCTP_DATA_UNSENT,
@@ -570,7 +570,7 @@
struct sctp_getaddrs {
sctp_assoc_t assoc_id;
__u32 addr_num;
- __u8 addrs[0];
+ __u8 addrs[];
};
struct sctp_assoc_stats {
sctp_assoc_t sas_assoc_id;
diff --git a/libc/kernel/uapi/linux/seccomp.h b/libc/kernel/uapi/linux/seccomp.h
index e58b421..cc506ae 100644
--- a/libc/kernel/uapi/linux/seccomp.h
+++ b/libc/kernel/uapi/linux/seccomp.h
@@ -32,6 +32,7 @@
#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)
#define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3)
#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4)
+#define SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV (1UL << 5)
#define SECCOMP_RET_KILL_PROCESS 0x80000000U
#define SECCOMP_RET_KILL_THREAD 0x00000000U
#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
diff --git a/libc/kernel/uapi/linux/seg6.h b/libc/kernel/uapi/linux/seg6.h
index f180485..b8206cc 100644
--- a/libc/kernel/uapi/linux/seg6.h
+++ b/libc/kernel/uapi/linux/seg6.h
@@ -28,7 +28,7 @@
__u8 first_segment;
__u8 flags;
__u16 tag;
- struct in6_addr segments[0];
+ struct in6_addr segments[];
};
#define SR6_FLAG1_PROTECTED (1 << 6)
#define SR6_FLAG1_OAM (1 << 5)
diff --git a/libc/kernel/uapi/linux/seg6_iptunnel.h b/libc/kernel/uapi/linux/seg6_iptunnel.h
index 1c1ad83..19d8ba4 100644
--- a/libc/kernel/uapi/linux/seg6_iptunnel.h
+++ b/libc/kernel/uapi/linux/seg6_iptunnel.h
@@ -27,12 +27,14 @@
#define SEG6_IPTUNNEL_MAX (__SEG6_IPTUNNEL_MAX - 1)
struct seg6_iptunnel_encap {
int mode;
- struct ipv6_sr_hdr srh[0];
+ struct ipv6_sr_hdr srh[];
};
#define SEG6_IPTUN_ENCAP_SIZE(x) ((sizeof(* x)) + (((x)->srh->hdrlen + 1) << 3))
enum {
SEG6_IPTUN_MODE_INLINE,
SEG6_IPTUN_MODE_ENCAP,
SEG6_IPTUN_MODE_L2ENCAP,
+ SEG6_IPTUN_MODE_ENCAP_RED,
+ SEG6_IPTUN_MODE_L2ENCAP_RED,
};
#endif
diff --git a/libc/kernel/uapi/linux/serial.h b/libc/kernel/uapi/linux/serial.h
index e4e903d..5a83c62 100644
--- a/libc/kernel/uapi/linux/serial.h
+++ b/libc/kernel/uapi/linux/serial.h
@@ -96,9 +96,20 @@
#define SER_RS485_RTS_AFTER_SEND (1 << 2)
#define SER_RS485_RX_DURING_TX (1 << 4)
#define SER_RS485_TERMINATE_BUS (1 << 5)
+#define SER_RS485_ADDRB (1 << 6)
+#define SER_RS485_ADDR_RECV (1 << 7)
+#define SER_RS485_ADDR_DEST (1 << 8)
__u32 delay_rts_before_send;
__u32 delay_rts_after_send;
- __u32 padding[5];
+ union {
+ __u32 padding[5];
+ struct {
+ __u8 addr_recv;
+ __u8 addr_dest;
+ __u8 padding0[2];
+ __u32 padding1[4];
+ };
+ };
};
struct serial_iso7816 {
__u32 flags;
diff --git a/libc/kernel/uapi/linux/serial_core.h b/libc/kernel/uapi/linux/serial_core.h
index 0caf698..1e04429 100644
--- a/libc/kernel/uapi/linux/serial_core.h
+++ b/libc/kernel/uapi/linux/serial_core.h
@@ -47,6 +47,7 @@
#define PORT_SUNSAB 39
#define PORT_NPCM 40
#define PORT_TEGRA_TCU 41
+#define PORT_ASPEED_VUART 42
#define PORT_PCH_8LINE 44
#define PORT_PCH_2LINE 45
#define PORT_DZ 46
@@ -68,8 +69,6 @@
#define PORT_IMX 62
#define PORT_MPSC 63
#define PORT_TXX9 64
-#define PORT_VR41XX_SIU 65
-#define PORT_VR41XX_DSIU 66
#define PORT_S3C2400 67
#define PORT_M32R_SIO 68
#define PORT_JSM 69
@@ -122,4 +121,5 @@
#define PORT_SIFIVE_V0 120
#define PORT_SUNIX 121
#define PORT_LINFLEXUART 122
+#define PORT_SUNPLUS 123
#endif
diff --git a/libc/kernel/uapi/linux/serial_reg.h b/libc/kernel/uapi/linux/serial_reg.h
index b6648f8..e41e649 100644
--- a/libc/kernel/uapi/linux/serial_reg.h
+++ b/libc/kernel/uapi/linux/serial_reg.h
@@ -99,7 +99,7 @@
#define UART_LSR_PE 0x04
#define UART_LSR_OE 0x02
#define UART_LSR_DR 0x01
-#define UART_LSR_BRK_ERROR_BITS 0x1E
+#define UART_LSR_BRK_ERROR_BITS (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE | UART_LSR_OE)
#define UART_MSR 6
#define UART_MSR_DCD 0x80
#define UART_MSR_RI 0x40
@@ -109,7 +109,7 @@
#define UART_MSR_TERI 0x04
#define UART_MSR_DDSR 0x02
#define UART_MSR_DCTS 0x01
-#define UART_MSR_ANY_DELTA 0x0F
+#define UART_MSR_ANY_DELTA (UART_MSR_DDCD | UART_MSR_TERI | UART_MSR_DDSR | UART_MSR_DCTS)
#define UART_SCR 7
#define UART_DLL 0
#define UART_DLM 1
diff --git a/libc/kernel/uapi/linux/sev-guest.h b/libc/kernel/uapi/linux/sev-guest.h
new file mode 100644
index 0000000..796479a
--- /dev/null
+++ b/libc/kernel/uapi/linux/sev-guest.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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_SEV_GUEST_H_
+#define __UAPI_LINUX_SEV_GUEST_H_
+#include <linux/types.h>
+struct snp_report_req {
+ __u8 user_data[64];
+ __u32 vmpl;
+ __u8 rsvd[28];
+};
+struct snp_report_resp {
+ __u8 data[4000];
+};
+struct snp_derived_key_req {
+ __u32 root_key_select;
+ __u32 rsvd;
+ __u64 guest_field_select;
+ __u32 vmpl;
+ __u32 guest_svn;
+ __u64 tcb_version;
+};
+struct snp_derived_key_resp {
+ __u8 data[64];
+};
+struct snp_guest_request_ioctl {
+ __u8 msg_version;
+ __u64 req_data;
+ __u64 resp_data;
+ __u64 fw_err;
+};
+struct snp_ext_report_req {
+ struct snp_report_req data;
+ __u64 certs_address;
+ __u32 certs_len;
+};
+#define SNP_GUEST_REQ_IOC_TYPE 'S'
+#define SNP_GET_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x0, struct snp_guest_request_ioctl)
+#define SNP_GET_DERIVED_KEY _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x1, struct snp_guest_request_ioctl)
+#define SNP_GET_EXT_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x2, struct snp_guest_request_ioctl)
+#endif
diff --git a/libc/kernel/uapi/linux/smc.h b/libc/kernel/uapi/linux/smc.h
index 01494da..200c9b6 100644
--- a/libc/kernel/uapi/linux/smc.h
+++ b/libc/kernel/uapi/linux/smc.h
@@ -57,6 +57,9 @@
SMC_NETLINK_DUMP_SEID,
SMC_NETLINK_ENABLE_SEID,
SMC_NETLINK_DISABLE_SEID,
+ SMC_NETLINK_DUMP_HS_LIMITATION,
+ SMC_NETLINK_ENABLE_HS_LIMITATION,
+ SMC_NETLINK_DISABLE_HS_LIMITATION,
};
enum {
SMC_GEN_UNSPEC,
@@ -109,6 +112,7 @@
SMC_NLA_LGR_R_V2,
SMC_NLA_LGR_R_NET_COOKIE,
SMC_NLA_LGR_R_PAD,
+ SMC_NLA_LGR_R_BUF_TYPE,
__SMC_NLA_LGR_R_MAX,
SMC_NLA_LGR_R_MAX = __SMC_NLA_LGR_R_MAX - 1
};
@@ -249,4 +253,11 @@
__SMC_NLA_SEID_TABLE_MAX,
SMC_NLA_SEID_TABLE_MAX = __SMC_NLA_SEID_TABLE_MAX - 1
};
+enum {
+ SMC_NLA_HS_LIMITATION_UNSPEC,
+ SMC_NLA_HS_LIMITATION_ENABLED,
+ __SMC_NLA_HS_LIMITATION_MAX,
+ SMC_NLA_HS_LIMITATION_MAX = __SMC_NLA_HS_LIMITATION_MAX - 1
+};
+#define SMC_LIMIT_HS 1
#endif
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index a503a7e..d98f39e 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -305,6 +305,8 @@
LINUX_MIB_TLSRXDEVICE,
LINUX_MIB_TLSDECRYPTERROR,
LINUX_MIB_TLSRXDEVICERESYNC,
+ LINUX_MIB_TLSDECRYPTRETRY,
+ LINUX_MIB_TLSRXNOPADVIOL,
__LINUX_MIB_TLSMAX
};
#endif
diff --git a/libc/kernel/uapi/linux/socket.h b/libc/kernel/uapi/linux/socket.h
index be16548..4a530a8 100644
--- a/libc/kernel/uapi/linux/socket.h
+++ b/libc/kernel/uapi/linux/socket.h
@@ -32,4 +32,7 @@
#define SOCK_SNDBUF_LOCK 1
#define SOCK_RCVBUF_LOCK 2
#define SOCK_BUF_LOCK_MASK (SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK)
+#define SOCK_TXREHASH_DEFAULT 255
+#define SOCK_TXREHASH_DISABLED 0
+#define SOCK_TXREHASH_ENABLED 1
#endif
diff --git a/libc/kernel/uapi/linux/spi/spi.h b/libc/kernel/uapi/linux/spi/spi.h
index 39267a2..693e752 100644
--- a/libc/kernel/uapi/linux/spi/spi.h
+++ b/libc/kernel/uapi/linux/spi/spi.h
@@ -40,5 +40,6 @@
#define SPI_TX_OCTAL _BITUL(13)
#define SPI_RX_OCTAL _BITUL(14)
#define SPI_3WIRE_HIZ _BITUL(15)
-#define SPI_MODE_USER_MASK (_BITUL(16) - 1)
+#define SPI_RX_CPHA_FLIP _BITUL(16)
+#define SPI_MODE_USER_MASK (_BITUL(17) - 1)
#endif
diff --git a/libc/kernel/uapi/linux/stddef.h b/libc/kernel/uapi/linux/stddef.h
index d5cdf80..6bc6925 100644
--- a/libc/kernel/uapi/linux/stddef.h
+++ b/libc/kernel/uapi/linux/stddef.h
@@ -16,9 +16,12 @@
***
****************************************************************************
****************************************************************************/
+#ifndef _UAPI_LINUX_STDDEF_H
+#define _UAPI_LINUX_STDDEF_H
#include <linux/compiler_types.h>
#ifndef __always_inline
#define __always_inline inline
#endif
#define __struct_group(TAG,NAME,ATTRS,MEMBERS...) union { struct { MEMBERS } ATTRS; struct TAG { MEMBERS } ATTRS NAME; }
#define __DECLARE_FLEX_ARRAY(TYPE,NAME) struct { struct { } __empty_ ##NAME; TYPE NAME[]; }
+#endif
diff --git a/libc/kernel/uapi/linux/stm.h b/libc/kernel/uapi/linux/stm.h
index 1c7f7f3..b1453f7 100644
--- a/libc/kernel/uapi/linux/stm.h
+++ b/libc/kernel/uapi/linux/stm.h
@@ -28,7 +28,7 @@
__u16 width;
__u16 __reserved_0;
__u32 __reserved_1;
- char id[0];
+ char id[];
};
#define STP_POLICY_ID_SET _IOWR('%', 0, struct stp_policy_id)
#define STP_POLICY_ID_GET _IOR('%', 1, struct stp_policy_id)
diff --git a/libc/kernel/uapi/linux/sysctl.h b/libc/kernel/uapi/linux/sysctl.h
index ae9c2ba..ff17f7c 100644
--- a/libc/kernel/uapi/linux/sysctl.h
+++ b/libc/kernel/uapi/linux/sysctl.h
@@ -516,6 +516,7 @@
NET_NEIGH_GC_THRESH3 = 16,
NET_NEIGH_RETRANS_TIME_MS = 17,
NET_NEIGH_REACHABLE_TIME_MS = 18,
+ NET_NEIGH_INTERVAL_PROBE_TIME_MS = 19,
};
enum {
NET_DCCP_DEFAULT = 1,
diff --git a/libc/kernel/uapi/linux/target_core_user.h b/libc/kernel/uapi/linux/target_core_user.h
index dcba00e..daecb7d 100644
--- a/libc/kernel/uapi/linux/target_core_user.h
+++ b/libc/kernel/uapi/linux/target_core_user.h
@@ -89,7 +89,7 @@
__u32 cmd_cnt;
__u64 __pad3;
__u64 __pad4;
- __u16 cmd_ids[0];
+ __u16 cmd_ids[];
} __packed;
#define TCMU_OP_ALIGN_SIZE sizeof(__u64)
enum tcmu_genl_cmd {
diff --git a/libc/kernel/uapi/linux/taskstats.h b/libc/kernel/uapi/linux/taskstats.h
index efa5b4a..c1cda52 100644
--- a/libc/kernel/uapi/linux/taskstats.h
+++ b/libc/kernel/uapi/linux/taskstats.h
@@ -19,7 +19,7 @@
#ifndef _LINUX_TASKSTATS_H
#define _LINUX_TASKSTATS_H
#include <linux/types.h>
-#define TASKSTATS_VERSION 11
+#define TASKSTATS_VERSION 13
#define TS_COMM_LEN 32
struct taskstats {
__u16 version;
@@ -71,6 +71,12 @@
__u64 ac_btime64;
__u64 compact_count;
__u64 compact_delay_total;
+ __u32 ac_tgid;
+ __u64 ac_tgetime __attribute__((aligned(8)));
+ __u64 ac_exe_dev;
+ __u64 ac_exe_inode;
+ __u64 wpcopy_count;
+ __u64 wpcopy_delay_total;
};
enum {
TASKSTATS_CMD_UNSPEC = 0,
diff --git a/libc/kernel/uapi/linux/tc_act/tc_skbedit.h b/libc/kernel/uapi/linux/tc_act/tc_skbedit.h
index 5706d4d..b041a6a 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_skbedit.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_skbedit.h
@@ -25,6 +25,7 @@
#define SKBEDIT_F_PTYPE 0x8
#define SKBEDIT_F_MASK 0x10
#define SKBEDIT_F_INHERITDSFIELD 0x20
+#define SKBEDIT_F_TXQ_SKBHASH 0x40
struct tc_skbedit {
tc_gen;
};
@@ -39,6 +40,7 @@
TCA_SKBEDIT_PTYPE,
TCA_SKBEDIT_MASK,
TCA_SKBEDIT_FLAGS,
+ TCA_SKBEDIT_QUEUE_MAPPING_MAX,
__TCA_SKBEDIT_MAX
};
#define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tee.h b/libc/kernel/uapi/linux/tee.h
index 5cfe713..404b7b2 100644
--- a/libc/kernel/uapi/linux/tee.h
+++ b/libc/kernel/uapi/linux/tee.h
@@ -22,8 +22,6 @@
#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_GEN_CAP_PRIVILEGED (1 << 1)
diff --git a/libc/kernel/uapi/linux/thermal.h b/libc/kernel/uapi/linux/thermal.h
index 72ea378..2f9dccb 100644
--- a/libc/kernel/uapi/linux/thermal.h
+++ b/libc/kernel/uapi/linux/thermal.h
@@ -54,6 +54,10 @@
THERMAL_GENL_ATTR_CDEV_MAX_STATE,
THERMAL_GENL_ATTR_CDEV_NAME,
THERMAL_GENL_ATTR_GOV_NAME,
+ THERMAL_GENL_ATTR_CPU_CAPABILITY,
+ THERMAL_GENL_ATTR_CPU_CAPABILITY_ID,
+ THERMAL_GENL_ATTR_CPU_CAPABILITY_PERFORMANCE,
+ THERMAL_GENL_ATTR_CPU_CAPABILITY_EFFICIENCY,
__THERMAL_GENL_ATTR_MAX,
};
#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1)
@@ -77,6 +81,7 @@
THERMAL_GENL_EVENT_CDEV_DELETE,
THERMAL_GENL_EVENT_CDEV_STATE_UPDATE,
THERMAL_GENL_EVENT_TZ_GOV_CHANGE,
+ THERMAL_GENL_EVENT_CPU_CAPABILITY_CHANGE,
__THERMAL_GENL_EVENT_MAX,
};
#define THERMAL_GENL_EVENT_MAX (__THERMAL_GENL_EVENT_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tipc_config.h b/libc/kernel/uapi/linux/tipc_config.h
index a371e37..c6ee1d1 100644
--- a/libc/kernel/uapi/linux/tipc_config.h
+++ b/libc/kernel/uapi/linux/tipc_config.h
@@ -22,7 +22,6 @@
#include <linux/string.h>
#include <linux/tipc.h>
#include <asm/byteorder.h>
-#include <arpa/inet.h>
#define TIPC_CMD_NOOP 0x0000
#define TIPC_CMD_GET_NODES 0x0001
#define TIPC_CMD_GET_MEDIA_NAMES 0x0002
diff --git a/libc/kernel/uapi/linux/tls.h b/libc/kernel/uapi/linux/tls.h
index c98ea0b..d327d66 100644
--- a/libc/kernel/uapi/linux/tls.h
+++ b/libc/kernel/uapi/linux/tls.h
@@ -21,6 +21,8 @@
#include <linux/types.h>
#define TLS_TX 1
#define TLS_RX 2
+#define TLS_TX_ZEROCOPY_RO 3
+#define TLS_RX_EXPECT_NO_PAD 4
#define TLS_VERSION_MINOR(ver) ((ver) & 0xFF)
#define TLS_VERSION_MAJOR(ver) (((ver) >> 8) & 0xFF)
#define TLS_VERSION_NUMBER(id) ((((id ##_VERSION_MAJOR) & 0xFF) << 8) | ((id ##_VERSION_MINOR) & 0xFF))
@@ -120,6 +122,8 @@
TLS_INFO_CIPHER,
TLS_INFO_TXCONF,
TLS_INFO_RXCONF,
+ TLS_INFO_ZC_RO_TX,
+ TLS_INFO_RX_NO_PAD,
__TLS_INFO_MAX,
};
#define TLS_INFO_MAX (__TLS_INFO_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tty.h b/libc/kernel/uapi/linux/tty.h
index dcce572..a94e6e6 100644
--- a/libc/kernel/uapi/linux/tty.h
+++ b/libc/kernel/uapi/linux/tty.h
@@ -18,7 +18,6 @@
****************************************************************************/
#ifndef _UAPI_LINUX_TTY_H
#define _UAPI_LINUX_TTY_H
-#define NR_LDISCS 30
#define N_TTY 0
#define N_SLIP 1
#define N_MOUSE 2
@@ -48,4 +47,7 @@
#define N_SPEAKUP 26
#define N_NULL 27
#define N_MCTP 28
+#define N_DEVELOPMENT 29
+#define N_CAN327 30
+#define NR_LDISCS 31
#endif
diff --git a/libc/kernel/uapi/linux/types.h b/libc/kernel/uapi/linux/types.h
index 9145e66..f41d676 100644
--- a/libc/kernel/uapi/linux/types.h
+++ b/libc/kernel/uapi/linux/types.h
@@ -21,8 +21,8 @@
#include <asm/types.h>
#ifndef __ASSEMBLY__
#include <linux/posix_types.h>
-#define __bitwise__
-#define __bitwise __bitwise__
+#define __bitwise
+#define __bitwise__ __bitwise
typedef __u16 __bitwise __le16;
typedef __u16 __bitwise __be16;
typedef __u32 __bitwise __le32;
diff --git a/libc/kernel/uapi/linux/ublk_cmd.h b/libc/kernel/uapi/linux/ublk_cmd.h
new file mode 100644
index 0000000..caf7f93
--- /dev/null
+++ b/libc/kernel/uapi/linux/ublk_cmd.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 USER_BLK_DRV_CMD_INC_H
+#define USER_BLK_DRV_CMD_INC_H
+#include <linux/types.h>
+#define UBLK_CMD_GET_QUEUE_AFFINITY 0x01
+#define UBLK_CMD_GET_DEV_INFO 0x02
+#define UBLK_CMD_ADD_DEV 0x04
+#define UBLK_CMD_DEL_DEV 0x05
+#define UBLK_CMD_START_DEV 0x06
+#define UBLK_CMD_STOP_DEV 0x07
+#define UBLK_CMD_SET_PARAMS 0x08
+#define UBLK_CMD_GET_PARAMS 0x09
+#define UBLK_IO_FETCH_REQ 0x20
+#define UBLK_IO_COMMIT_AND_FETCH_REQ 0x21
+#define UBLK_IO_NEED_GET_DATA 0x22
+#define UBLK_IO_RES_OK 0
+#define UBLK_IO_RES_NEED_GET_DATA 1
+#define UBLK_IO_RES_ABORT (- ENODEV)
+#define UBLKSRV_CMD_BUF_OFFSET 0
+#define UBLKSRV_IO_BUF_OFFSET 0x80000000
+#define UBLK_MAX_QUEUE_DEPTH 4096
+#define UBLK_F_SUPPORT_ZERO_COPY (1ULL << 0)
+#define UBLK_F_URING_CMD_COMP_IN_TASK (1ULL << 1)
+#define UBLK_F_NEED_GET_DATA (1UL << 2)
+#define UBLK_S_DEV_DEAD 0
+#define UBLK_S_DEV_LIVE 1
+struct ublksrv_ctrl_cmd {
+ __u32 dev_id;
+ __u16 queue_id;
+ __u16 len;
+ __u64 addr;
+ __u64 data[2];
+};
+struct ublksrv_ctrl_dev_info {
+ __u16 nr_hw_queues;
+ __u16 queue_depth;
+ __u16 state;
+ __u16 pad0;
+ __u32 max_io_buf_bytes;
+ __u32 dev_id;
+ __s32 ublksrv_pid;
+ __u32 pad1;
+ __u64 flags;
+ __u64 ublksrv_flags;
+ __u64 reserved0;
+ __u64 reserved1;
+ __u64 reserved2;
+};
+#define UBLK_IO_OP_READ 0
+#define UBLK_IO_OP_WRITE 1
+#define UBLK_IO_OP_FLUSH 2
+#define UBLK_IO_OP_DISCARD 3
+#define UBLK_IO_OP_WRITE_SAME 4
+#define UBLK_IO_OP_WRITE_ZEROES 5
+#define UBLK_IO_F_FAILFAST_DEV (1U << 8)
+#define UBLK_IO_F_FAILFAST_TRANSPORT (1U << 9)
+#define UBLK_IO_F_FAILFAST_DRIVER (1U << 10)
+#define UBLK_IO_F_META (1U << 11)
+#define UBLK_IO_F_FUA (1U << 13)
+#define UBLK_IO_F_NOUNMAP (1U << 15)
+#define UBLK_IO_F_SWAP (1U << 16)
+struct ublksrv_io_desc {
+ __u32 op_flags;
+ __u32 nr_sectors;
+ __u64 start_sector;
+ __u64 addr;
+};
+struct ublksrv_io_cmd {
+ __u16 q_id;
+ __u16 tag;
+ __s32 result;
+ __u64 addr;
+};
+struct ublk_param_basic {
+#define UBLK_ATTR_READ_ONLY (1 << 0)
+#define UBLK_ATTR_ROTATIONAL (1 << 1)
+#define UBLK_ATTR_VOLATILE_CACHE (1 << 2)
+#define UBLK_ATTR_FUA (1 << 3)
+ __u32 attrs;
+ __u8 logical_bs_shift;
+ __u8 physical_bs_shift;
+ __u8 io_opt_shift;
+ __u8 io_min_shift;
+ __u32 max_sectors;
+ __u32 chunk_sectors;
+ __u64 dev_sectors;
+ __u64 virt_boundary_mask;
+};
+struct ublk_param_discard {
+ __u32 discard_alignment;
+ __u32 discard_granularity;
+ __u32 max_discard_sectors;
+ __u32 max_write_zeroes_sectors;
+ __u16 max_discard_segments;
+ __u16 reserved0;
+};
+struct ublk_params {
+ __u32 len;
+#define UBLK_PARAM_TYPE_BASIC (1 << 0)
+#define UBLK_PARAM_TYPE_DISCARD (1 << 1)
+ __u32 types;
+ struct ublk_param_basic basic;
+ struct ublk_param_discard discard;
+};
+#endif
diff --git a/libc/kernel/uapi/linux/usb/audio.h b/libc/kernel/uapi/linux/usb/audio.h
index 7d36157..bfda540 100644
--- a/libc/kernel/uapi/linux/usb/audio.h
+++ b/libc/kernel/uapi/linux/usb/audio.h
@@ -186,7 +186,7 @@
__u8 bUnitID;
__u8 bSourceID;
__u8 bControlSize;
- __u8 bmaControls[0];
+ __u8 bmaControls[];
} __attribute__((packed));
struct uac_processing_unit_descriptor {
__u8 bLength;
diff --git a/libc/kernel/uapi/linux/usb/cdc.h b/libc/kernel/uapi/linux/usb/cdc.h
index 59c9488..bbfc4db 100644
--- a/libc/kernel/uapi/linux/usb/cdc.h
+++ b/libc/kernel/uapi/linux/usb/cdc.h
@@ -131,7 +131,7 @@
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bGuidDescriptorType;
- __u8 bDetailData[0];
+ __u8 bDetailData[];
} __attribute__((packed));
struct usb_cdc_obex_desc {
__u8 bLength;
@@ -201,6 +201,8 @@
#define USB_CDC_SPACE_PARITY 4
__u8 bDataBits;
} __attribute__((packed));
+#define USB_CDC_CTRL_DTR (1 << 0)
+#define USB_CDC_CTRL_RTS (1 << 1)
#define USB_CDC_PACKET_TYPE_PROMISCUOUS (1 << 0)
#define USB_CDC_PACKET_TYPE_ALL_MULTICAST (1 << 1)
#define USB_CDC_PACKET_TYPE_DIRECTED (1 << 2)
@@ -217,6 +219,13 @@
__le16 wIndex;
__le16 wLength;
} __attribute__((packed));
+#define USB_CDC_SERIAL_STATE_DCD (1 << 0)
+#define USB_CDC_SERIAL_STATE_DSR (1 << 1)
+#define USB_CDC_SERIAL_STATE_BREAK (1 << 2)
+#define USB_CDC_SERIAL_STATE_RING_SIGNAL (1 << 3)
+#define USB_CDC_SERIAL_STATE_FRAMING (1 << 4)
+#define USB_CDC_SERIAL_STATE_PARITY (1 << 5)
+#define USB_CDC_SERIAL_STATE_OVERRUN (1 << 6)
struct usb_cdc_speed_change {
__le32 DLBitRRate;
__le32 ULBitRate;
@@ -267,7 +276,7 @@
__le32 dwSignature;
__le16 wLength;
__le16 wNextNdpIndex;
- struct usb_cdc_ncm_dpe16 dpe16[0];
+ struct usb_cdc_ncm_dpe16 dpe16[];
} __attribute__((packed));
struct usb_cdc_ncm_dpe32 {
__le32 dwDatagramIndex;
@@ -279,7 +288,7 @@
__le16 wReserved6;
__le32 dwNextNdpIndex;
__le32 dwReserved12;
- struct usb_cdc_ncm_dpe32 dpe32[0];
+ struct usb_cdc_ncm_dpe32 dpe32[];
} __attribute__((packed));
#define USB_CDC_NCM_NDP16_INDEX_MIN 0x000C
#define USB_CDC_NCM_NDP32_INDEX_MIN 0x0010
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index f1dade9..49eb5fa 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -324,7 +324,7 @@
__u8 bDescriptorType;
__u8 tTKID[3];
__u8 bReserved;
- __u8 bKeyData[0];
+ __u8 bKeyData[];
} __attribute__((packed));
struct usb_encryption_descriptor {
__u8 bLength;
diff --git a/libc/kernel/uapi/linux/usb/raw_gadget.h b/libc/kernel/uapi/linux/usb/raw_gadget.h
index 70d5a26..8b60c8d 100644
--- a/libc/kernel/uapi/linux/usb/raw_gadget.h
+++ b/libc/kernel/uapi/linux/usb/raw_gadget.h
@@ -35,7 +35,7 @@
struct usb_raw_event {
__u32 type;
__u32 length;
- __u8 data[0];
+ __u8 data[];
};
#define USB_RAW_IO_FLAGS_ZERO 0x0001
#define USB_RAW_IO_FLAGS_MASK 0x0001
@@ -43,7 +43,7 @@
__u16 ep;
__u16 flags;
__u32 length;
- __u8 data[0];
+ __u8 data[];
};
#define USB_RAW_EPS_NUM_MAX 30
#define USB_RAW_EP_NAME_MAX 16
diff --git a/libc/kernel/uapi/linux/usbdevice_fs.h b/libc/kernel/uapi/linux/usbdevice_fs.h
index 7936ad9..5fef522 100644
--- a/libc/kernel/uapi/linux/usbdevice_fs.h
+++ b/libc/kernel/uapi/linux/usbdevice_fs.h
@@ -91,7 +91,7 @@
int error_count;
unsigned int signr;
void __user * usercontext;
- struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+ struct usbdevfs_iso_packet_desc iso_frame_desc[];
};
struct usbdevfs_ioctl {
int ifno;
@@ -121,7 +121,7 @@
struct usbdevfs_streams {
unsigned int num_streams;
unsigned int num_eps;
- unsigned char eps[0];
+ unsigned char eps[];
};
#define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer)
#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
index ca7b7a5..46d7472 100644
--- a/libc/kernel/uapi/linux/userfaultfd.h
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -21,10 +21,10 @@
#include <linux/types.h>
#define UFFD_API ((__u64) 0xAA)
#define UFFD_API_REGISTER_MODES (UFFDIO_REGISTER_MODE_MISSING | UFFDIO_REGISTER_MODE_WP | UFFDIO_REGISTER_MODE_MINOR)
-#define UFFD_API_FEATURES (UFFD_FEATURE_PAGEFAULT_FLAG_WP | UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM | UFFD_FEATURE_SIGBUS | UFFD_FEATURE_THREAD_ID | UFFD_FEATURE_MINOR_HUGETLBFS | UFFD_FEATURE_MINOR_SHMEM)
+#define UFFD_API_FEATURES (UFFD_FEATURE_PAGEFAULT_FLAG_WP | UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM | UFFD_FEATURE_SIGBUS | UFFD_FEATURE_THREAD_ID | UFFD_FEATURE_MINOR_HUGETLBFS | UFFD_FEATURE_MINOR_SHMEM | UFFD_FEATURE_EXACT_ADDRESS | UFFD_FEATURE_WP_HUGETLBFS_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 | (__u64) 1 << _UFFDIO_WRITEPROTECT | (__u64) 1 << _UFFDIO_CONTINUE)
-#define UFFD_API_RANGE_IOCTLS_BASIC ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_CONTINUE)
+#define UFFD_API_RANGE_IOCTLS_BASIC ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_CONTINUE | (__u64) 1 << _UFFDIO_WRITEPROTECT)
#define _UFFDIO_REGISTER (0x00)
#define _UFFDIO_UNREGISTER (0x01)
#define _UFFDIO_WAKE (0x02)
@@ -95,6 +95,8 @@
#define UFFD_FEATURE_THREAD_ID (1 << 8)
#define UFFD_FEATURE_MINOR_HUGETLBFS (1 << 9)
#define UFFD_FEATURE_MINOR_SHMEM (1 << 10)
+#define UFFD_FEATURE_EXACT_ADDRESS (1 << 11)
+#define UFFD_FEATURE_WP_HUGETLBFS_SHMEM (1 << 12)
__u64 features;
__u64 ioctls;
};
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index 1a11355..9de38d1 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -119,6 +119,7 @@
#define V4L2_CID_USER_CODA_BASE (V4L2_CID_USER_BASE + 0x10e0)
#define V4L2_CID_USER_CCS_BASE (V4L2_CID_USER_BASE + 0x10f0)
#define V4L2_CID_USER_ALLEGRO_BASE (V4L2_CID_USER_BASE + 0x1170)
+#define V4L2_CID_USER_ISL7998X_BASE (V4L2_CID_USER_BASE + 0x1180)
#define V4L2_CID_CODEC_BASE (V4L2_CTRL_CLASS_CODEC | 0x900)
#define V4L2_CID_CODEC_CLASS (V4L2_CTRL_CLASS_CODEC | 1)
#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_CODEC_BASE + 0)
@@ -329,6 +330,11 @@
#define V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES (V4L2_CID_CODEC_BASE + 234)
#define V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR (V4L2_CID_CODEC_BASE + 235)
#define V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD (V4L2_CID_CODEC_BASE + 236)
+#define V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE (V4L2_CID_CODEC_BASE + 237)
+enum v4l2_mpeg_video_intra_refresh_period_type {
+ V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM = 0,
+ V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC = 1,
+};
#define V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL (V4L2_CID_CODEC_BASE + 270)
enum v4l2_mpeg_video_mpeg2_level {
V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW = 0,
@@ -1153,6 +1159,8 @@
#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01
#define V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC 0x02
#define V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD 0x04
+#define V4L2_H264_DECODE_PARAM_FLAG_PFRAME 0x08
+#define V4L2_H264_DECODE_PARAM_FLAG_BFRAME 0x10
#define V4L2_CID_STATELESS_H264_DECODE_PARAMS (V4L2_CID_CODEC_STATELESS_BASE + 7)
struct v4l2_ctrl_h264_decode_params {
struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES];
@@ -1323,6 +1331,204 @@
__u8 chroma_intra_quantiser_matrix[64];
__u8 chroma_non_intra_quantiser_matrix[64];
};
+#define V4L2_CID_STATELESS_HEVC_SPS (V4L2_CID_CODEC_STATELESS_BASE + 400)
+#define V4L2_CID_STATELESS_HEVC_PPS (V4L2_CID_CODEC_STATELESS_BASE + 401)
+#define V4L2_CID_STATELESS_HEVC_SLICE_PARAMS (V4L2_CID_CODEC_STATELESS_BASE + 402)
+#define V4L2_CID_STATELESS_HEVC_SCALING_MATRIX (V4L2_CID_CODEC_STATELESS_BASE + 403)
+#define V4L2_CID_STATELESS_HEVC_DECODE_PARAMS (V4L2_CID_CODEC_STATELESS_BASE + 404)
+#define V4L2_CID_STATELESS_HEVC_DECODE_MODE (V4L2_CID_CODEC_STATELESS_BASE + 405)
+#define V4L2_CID_STATELESS_HEVC_START_CODE (V4L2_CID_CODEC_STATELESS_BASE + 406)
+#define V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS (V4L2_CID_CODEC_STATELESS_BASE + 407)
+enum v4l2_stateless_hevc_decode_mode {
+ V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED,
+ V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
+};
+enum v4l2_stateless_hevc_start_code {
+ V4L2_STATELESS_HEVC_START_CODE_NONE,
+ V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
+};
+#define V4L2_HEVC_SLICE_TYPE_B 0
+#define V4L2_HEVC_SLICE_TYPE_P 1
+#define V4L2_HEVC_SLICE_TYPE_I 2
+#define V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE (1ULL << 0)
+#define V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED (1ULL << 1)
+#define V4L2_HEVC_SPS_FLAG_AMP_ENABLED (1ULL << 2)
+#define V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET (1ULL << 3)
+#define V4L2_HEVC_SPS_FLAG_PCM_ENABLED (1ULL << 4)
+#define V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED (1ULL << 5)
+#define V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT (1ULL << 6)
+#define V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED (1ULL << 7)
+#define V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED (1ULL << 8)
+struct v4l2_ctrl_hevc_sps {
+ __u8 video_parameter_set_id;
+ __u8 seq_parameter_set_id;
+ __u16 pic_width_in_luma_samples;
+ __u16 pic_height_in_luma_samples;
+ __u8 bit_depth_luma_minus8;
+ __u8 bit_depth_chroma_minus8;
+ __u8 log2_max_pic_order_cnt_lsb_minus4;
+ __u8 sps_max_dec_pic_buffering_minus1;
+ __u8 sps_max_num_reorder_pics;
+ __u8 sps_max_latency_increase_plus1;
+ __u8 log2_min_luma_coding_block_size_minus3;
+ __u8 log2_diff_max_min_luma_coding_block_size;
+ __u8 log2_min_luma_transform_block_size_minus2;
+ __u8 log2_diff_max_min_luma_transform_block_size;
+ __u8 max_transform_hierarchy_depth_inter;
+ __u8 max_transform_hierarchy_depth_intra;
+ __u8 pcm_sample_bit_depth_luma_minus1;
+ __u8 pcm_sample_bit_depth_chroma_minus1;
+ __u8 log2_min_pcm_luma_coding_block_size_minus3;
+ __u8 log2_diff_max_min_pcm_luma_coding_block_size;
+ __u8 num_short_term_ref_pic_sets;
+ __u8 num_long_term_ref_pics_sps;
+ __u8 chroma_format_idc;
+ __u8 sps_max_sub_layers_minus1;
+ __u8 reserved[6];
+ __u64 flags;
+};
+#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED (1ULL << 0)
+#define V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT (1ULL << 1)
+#define V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED (1ULL << 2)
+#define V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT (1ULL << 3)
+#define V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED (1ULL << 4)
+#define V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED (1ULL << 5)
+#define V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED (1ULL << 6)
+#define V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT (1ULL << 7)
+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED (1ULL << 8)
+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED (1ULL << 9)
+#define V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED (1ULL << 10)
+#define V4L2_HEVC_PPS_FLAG_TILES_ENABLED (1ULL << 11)
+#define V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED (1ULL << 12)
+#define V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED (1ULL << 13)
+#define V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 14)
+#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED (1ULL << 15)
+#define V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER (1ULL << 16)
+#define V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT (1ULL << 17)
+#define V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT (1ULL << 18)
+#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT (1ULL << 19)
+#define V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING (1ULL << 20)
+struct v4l2_ctrl_hevc_pps {
+ __u8 pic_parameter_set_id;
+ __u8 num_extra_slice_header_bits;
+ __u8 num_ref_idx_l0_default_active_minus1;
+ __u8 num_ref_idx_l1_default_active_minus1;
+ __s8 init_qp_minus26;
+ __u8 diff_cu_qp_delta_depth;
+ __s8 pps_cb_qp_offset;
+ __s8 pps_cr_qp_offset;
+ __u8 num_tile_columns_minus1;
+ __u8 num_tile_rows_minus1;
+ __u8 column_width_minus1[20];
+ __u8 row_height_minus1[22];
+ __s8 pps_beta_offset_div2;
+ __s8 pps_tc_offset_div2;
+ __u8 log2_parallel_merge_level_minus2;
+ __u8 reserved;
+ __u64 flags;
+};
+#define V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE 0x01
+#define V4L2_HEVC_SEI_PIC_STRUCT_FRAME 0
+#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_FIELD 1
+#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_FIELD 2
+#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_BOTTOM 3
+#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_TOP 4
+#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_BOTTOM_TOP 5
+#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM 6
+#define V4L2_HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING 7
+#define V4L2_HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING 8
+#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM 9
+#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP 10
+#define V4L2_HEVC_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM 11
+#define V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP 12
+#define V4L2_HEVC_DPB_ENTRIES_NUM_MAX 16
+struct v4l2_hevc_dpb_entry {
+ __u64 timestamp;
+ __u8 flags;
+ __u8 field_pic;
+ __u16 reserved;
+ __s32 pic_order_cnt_val;
+};
+struct v4l2_hevc_pred_weight_table {
+ __s8 delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __s8 luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __s8 delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
+ __s8 chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
+ __s8 delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __s8 luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __s8 delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
+ __s8 chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
+ __u8 luma_log2_weight_denom;
+ __s8 delta_chroma_log2_weight_denom;
+};
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA (1ULL << 0)
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA (1ULL << 1)
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED (1ULL << 2)
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO (1ULL << 3)
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT (1ULL << 4)
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0 (1ULL << 5)
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV (1ULL << 6)
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED (1ULL << 7)
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 8)
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 9)
+struct v4l2_ctrl_hevc_slice_params {
+ __u32 bit_size;
+ __u32 data_byte_offset;
+ __u32 num_entry_point_offsets;
+ __u8 nal_unit_type;
+ __u8 nuh_temporal_id_plus1;
+ __u8 slice_type;
+ __u8 colour_plane_id;
+ __s32 slice_pic_order_cnt;
+ __u8 num_ref_idx_l0_active_minus1;
+ __u8 num_ref_idx_l1_active_minus1;
+ __u8 collocated_ref_idx;
+ __u8 five_minus_max_num_merge_cand;
+ __s8 slice_qp_delta;
+ __s8 slice_cb_qp_offset;
+ __s8 slice_cr_qp_offset;
+ __s8 slice_act_y_qp_offset;
+ __s8 slice_act_cb_qp_offset;
+ __s8 slice_act_cr_qp_offset;
+ __s8 slice_beta_offset_div2;
+ __s8 slice_tc_offset_div2;
+ __u8 pic_struct;
+ __u8 reserved0[3];
+ __u32 slice_segment_addr;
+ __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __u16 short_term_ref_pic_set_size;
+ __u16 long_term_ref_pic_set_size;
+ struct v4l2_hevc_pred_weight_table pred_weight_table;
+ __u8 reserved1[2];
+ __u64 flags;
+};
+#define V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC 0x1
+#define V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC 0x2
+#define V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR 0x4
+struct v4l2_ctrl_hevc_decode_params {
+ __s32 pic_order_cnt_val;
+ __u16 short_term_ref_pic_set_size;
+ __u16 long_term_ref_pic_set_size;
+ __u8 num_active_dpb_entries;
+ __u8 num_poc_st_curr_before;
+ __u8 num_poc_st_curr_after;
+ __u8 num_poc_lt_curr;
+ __u8 poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __u8 poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __u8 poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __u8 reserved[4];
+ struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
+ __u64 flags;
+};
+struct v4l2_ctrl_hevc_scaling_matrix {
+ __u8 scaling_list_4x4[6][16];
+ __u8 scaling_list_8x8[6][64];
+ __u8 scaling_list_16x16[6][64];
+ __u8 scaling_list_32x32[2][64];
+ __u8 scaling_list_dc_coef_16x16[6];
+ __u8 scaling_list_dc_coef_32x32[2];
+};
#define V4L2_CID_COLORIMETRY_CLASS_BASE (V4L2_CTRL_CLASS_COLORIMETRY | 0x900)
#define V4L2_CID_COLORIMETRY_CLASS (V4L2_CTRL_CLASS_COLORIMETRY | 1)
#define V4L2_CID_COLORIMETRY_HDR10_CLL_INFO (V4L2_CID_COLORIMETRY_CLASS_BASE + 0)
diff --git a/libc/kernel/uapi/linux/vdpa.h b/libc/kernel/uapi/linux/vdpa.h
index b3e5d39..8b3be00 100644
--- a/libc/kernel/uapi/linux/vdpa.h
+++ b/libc/kernel/uapi/linux/vdpa.h
@@ -28,6 +28,7 @@
VDPA_CMD_DEV_DEL,
VDPA_CMD_DEV_GET,
VDPA_CMD_DEV_CONFIG_GET,
+ VDPA_CMD_DEV_VSTATS_GET,
};
enum vdpa_attr {
VDPA_ATTR_UNSPEC,
@@ -48,6 +49,9 @@
VDPA_ATTR_DEV_NEGOTIATED_FEATURES,
VDPA_ATTR_DEV_MGMTDEV_MAX_VQS,
VDPA_ATTR_DEV_SUPPORTED_FEATURES,
+ VDPA_ATTR_DEV_QUEUE_INDEX,
+ VDPA_ATTR_DEV_VENDOR_ATTR_NAME,
+ VDPA_ATTR_DEV_VENDOR_ATTR_VALUE,
VDPA_ATTR_MAX,
};
#endif
diff --git a/libc/kernel/uapi/linux/vduse.h b/libc/kernel/uapi/linux/vduse.h
index 2dc8c82..f0b6d6b 100644
--- a/libc/kernel/uapi/linux/vduse.h
+++ b/libc/kernel/uapi/linux/vduse.h
@@ -90,6 +90,22 @@
};
#define VDUSE_VQ_SETUP_KICKFD _IOW(VDUSE_BASE, 0x16, struct vduse_vq_eventfd)
#define VDUSE_VQ_INJECT_IRQ _IOW(VDUSE_BASE, 0x17, __u32)
+struct vduse_iova_umem {
+ __u64 uaddr;
+ __u64 iova;
+ __u64 size;
+ __u64 reserved[3];
+};
+#define VDUSE_IOTLB_REG_UMEM _IOW(VDUSE_BASE, 0x18, struct vduse_iova_umem)
+#define VDUSE_IOTLB_DEREG_UMEM _IOW(VDUSE_BASE, 0x19, struct vduse_iova_umem)
+struct vduse_iova_info {
+ __u64 start;
+ __u64 last;
+#define VDUSE_IOVA_CAP_UMEM (1 << 0)
+ __u64 capability;
+ __u64 reserved[3];
+};
+#define VDUSE_IOTLB_GET_INFO _IOWR(VDUSE_BASE, 0x1a, struct vduse_iova_info)
enum vduse_req_type {
VDUSE_GET_VQ_STATE,
VDUSE_SET_STATUS,
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 2dfd696..c194345 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,8 +16,8 @@
***
****************************************************************************
****************************************************************************/
-#define LINUX_VERSION_CODE 332032
+#define LINUX_VERSION_CODE 393216
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
-#define LINUX_VERSION_MAJOR 5
-#define LINUX_VERSION_PATCHLEVEL 17
+#define LINUX_VERSION_MAJOR 6
+#define LINUX_VERSION_PATCHLEVEL 0
#define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/vfio.h b/libc/kernel/uapi/linux/vfio.h
index e0f322b..8075408 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -110,7 +110,7 @@
#define VFIO_REGION_TYPE_PCI_VENDOR_MASK (0xffff)
#define VFIO_REGION_TYPE_GFX (1)
#define VFIO_REGION_TYPE_CCW (2)
-#define VFIO_REGION_TYPE_MIGRATION (3)
+#define VFIO_REGION_TYPE_MIGRATION_DEPRECATED (3)
#define VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION (1)
#define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
#define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG (3)
@@ -130,17 +130,17 @@
#define VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD (1)
#define VFIO_REGION_SUBTYPE_CCW_SCHIB (2)
#define VFIO_REGION_SUBTYPE_CCW_CRW (3)
-#define VFIO_REGION_SUBTYPE_MIGRATION (1)
+#define VFIO_REGION_SUBTYPE_MIGRATION_DEPRECATED (1)
struct vfio_device_migration_info {
__u32 device_state;
-#define VFIO_DEVICE_STATE_STOP (0)
-#define VFIO_DEVICE_STATE_RUNNING (1 << 0)
-#define VFIO_DEVICE_STATE_SAVING (1 << 1)
-#define VFIO_DEVICE_STATE_RESUMING (1 << 2)
-#define VFIO_DEVICE_STATE_MASK (VFIO_DEVICE_STATE_RUNNING | VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RESUMING)
-#define VFIO_DEVICE_STATE_VALID(state) (state & VFIO_DEVICE_STATE_RESUMING ? (state & VFIO_DEVICE_STATE_MASK) == VFIO_DEVICE_STATE_RESUMING : 1)
-#define VFIO_DEVICE_STATE_IS_ERROR(state) ((state & VFIO_DEVICE_STATE_MASK) == (VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RESUMING))
-#define VFIO_DEVICE_STATE_SET_ERROR(state) ((state & ~VFIO_DEVICE_STATE_MASK) | VFIO_DEVICE_SATE_SAVING | VFIO_DEVICE_STATE_RESUMING)
+#define VFIO_DEVICE_STATE_V1_STOP (0)
+#define VFIO_DEVICE_STATE_V1_RUNNING (1 << 0)
+#define VFIO_DEVICE_STATE_V1_SAVING (1 << 1)
+#define VFIO_DEVICE_STATE_V1_RESUMING (1 << 2)
+#define VFIO_DEVICE_STATE_MASK (VFIO_DEVICE_STATE_V1_RUNNING | VFIO_DEVICE_STATE_V1_SAVING | VFIO_DEVICE_STATE_V1_RESUMING)
+#define VFIO_DEVICE_STATE_VALID(state) (state & VFIO_DEVICE_STATE_V1_RESUMING ? (state & VFIO_DEVICE_STATE_MASK) == VFIO_DEVICE_STATE_V1_RESUMING : 1)
+#define VFIO_DEVICE_STATE_IS_ERROR(state) ((state & VFIO_DEVICE_STATE_MASK) == (VFIO_DEVICE_STATE_V1_SAVING | VFIO_DEVICE_STATE_V1_RESUMING))
+#define VFIO_DEVICE_STATE_SET_ERROR(state) ((state & ~VFIO_DEVICE_STATE_MASK) | VFIO_DEVICE_STATE_V1_SAVING | VFIO_DEVICE_STATE_V1_RESUMING)
__u32 reserved;
__u64 pending_bytes;
__u64 data_offset;
@@ -285,6 +285,25 @@
};
#define VFIO_DEVICE_FEATURE _IO(VFIO_TYPE, VFIO_BASE + 17)
#define VFIO_DEVICE_FEATURE_PCI_VF_TOKEN (0)
+struct vfio_device_feature_migration {
+ __aligned_u64 flags;
+#define VFIO_MIGRATION_STOP_COPY (1 << 0)
+#define VFIO_MIGRATION_P2P (1 << 1)
+};
+#define VFIO_DEVICE_FEATURE_MIGRATION 1
+struct vfio_device_feature_mig_state {
+ __u32 device_state;
+ __s32 data_fd;
+};
+#define VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE 2
+enum vfio_device_mig_state {
+ VFIO_DEVICE_STATE_ERROR = 0,
+ VFIO_DEVICE_STATE_STOP = 1,
+ VFIO_DEVICE_STATE_RUNNING = 2,
+ VFIO_DEVICE_STATE_STOP_COPY = 3,
+ VFIO_DEVICE_STATE_RESUMING = 4,
+ VFIO_DEVICE_STATE_RUNNING_P2P = 5,
+};
struct vfio_iommu_type1_info {
__u32 argsz;
__u32 flags;
diff --git a/libc/kernel/uapi/linux/vfio_zdev.h b/libc/kernel/uapi/linux/vfio_zdev.h
index c678e9a..1c3a943 100644
--- a/libc/kernel/uapi/linux/vfio_zdev.h
+++ b/libc/kernel/uapi/linux/vfio_zdev.h
@@ -29,6 +29,7 @@
__u16 fmb_length;
__u8 pft;
__u8 gid;
+ __u32 fh;
};
struct vfio_device_info_cap_zpci_group {
struct vfio_info_cap_header header;
@@ -40,6 +41,8 @@
__u16 noi;
__u16 maxstbl;
__u8 version;
+ __u8 reserved;
+ __u16 imaxstbl;
};
struct vfio_device_info_cap_zpci_util {
struct vfio_info_cap_header header;
diff --git a/libc/kernel/uapi/linux/vhost.h b/libc/kernel/uapi/linux/vhost.h
index 53b01c4..e5b1327 100644
--- a/libc/kernel/uapi/linux/vhost.h
+++ b/libc/kernel/uapi/linux/vhost.h
@@ -43,8 +43,6 @@
#define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file)
#define VHOST_SET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x23, struct vhost_vring_state)
#define VHOST_GET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x24, struct vhost_vring_state)
-#define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1
-#define VHOST_BACKEND_F_IOTLB_BATCH 0x2
#define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
#define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
#define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file)
@@ -64,4 +62,11 @@
#define VHOST_VDPA_GET_VRING_NUM _IOR(VHOST_VIRTIO, 0x76, __u16)
#define VHOST_VDPA_SET_CONFIG_CALL _IOW(VHOST_VIRTIO, 0x77, int)
#define VHOST_VDPA_GET_IOVA_RANGE _IOR(VHOST_VIRTIO, 0x78, struct vhost_vdpa_iova_range)
+#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x79, __u32)
+#define VHOST_VDPA_GET_VQS_COUNT _IOR(VHOST_VIRTIO, 0x80, __u32)
+#define VHOST_VDPA_GET_GROUP_NUM _IOR(VHOST_VIRTIO, 0x81, __u32)
+#define VHOST_VDPA_GET_AS_NUM _IOR(VHOST_VIRTIO, 0x7A, unsigned int)
+#define VHOST_VDPA_GET_VRING_GROUP _IOWR(VHOST_VIRTIO, 0x7B, struct vhost_vring_state)
+#define VHOST_VDPA_SET_GROUP_ASID _IOW(VHOST_VIRTIO, 0x7C, struct vhost_vring_state)
+#define VHOST_VDPA_SUSPEND _IO(VHOST_VIRTIO, 0x7D)
#endif
diff --git a/libc/kernel/uapi/linux/vhost_types.h b/libc/kernel/uapi/linux/vhost_types.h
index 6b4cc77..32efa85 100644
--- a/libc/kernel/uapi/linux/vhost_types.h
+++ b/libc/kernel/uapi/linux/vhost_types.h
@@ -66,7 +66,7 @@
};
struct vhost_msg_v2 {
__u32 type;
- __u32 reserved;
+ __u32 asid;
union {
struct vhost_iotlb_msg iotlb;
__u8 padding[64];
@@ -82,7 +82,7 @@
struct vhost_memory {
__u32 nregions;
__u32 padding;
- struct vhost_memory_region regions[0];
+ struct vhost_memory_region regions[];
};
#define VHOST_SCSI_ABI_VERSION 1
struct vhost_scsi_target {
@@ -94,7 +94,7 @@
struct vhost_vdpa_config {
__u32 off;
__u32 len;
- __u8 buf[0];
+ __u8 buf[];
};
struct vhost_vdpa_iova_range {
__u64 first;
@@ -102,4 +102,8 @@
};
#define VHOST_F_LOG_ALL 26
#define VHOST_NET_F_VIRTIO_NET_HDR 27
+#define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1
+#define VHOST_BACKEND_F_IOTLB_BATCH 0x2
+#define VHOST_BACKEND_F_IOTLB_ASID 0x3
+#define VHOST_BACKEND_F_SUSPEND 0x4
#endif
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 74bd328..9fc33a4 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -24,12 +24,7 @@
#include <linux/types.h>
#include <linux/v4l2-common.h>
#include <linux/v4l2-controls.h>
-/* ---------------------------------------------------
- * This value manually changed due to b/228783882.
- * Next kernel update should keep this value as is.
- */
#define VIDEO_MAX_FRAME 64
-/* --------------------------------------------------- */
#define VIDEO_MAX_PLANES 8
#define v4l2_fourcc(a,b,c,d) ((__u32) (a) | ((__u32) (b) << 8) | ((__u32) (c) << 16) | ((__u32) (d) << 24))
#define v4l2_fourcc_be(a,b,c,d) (v4l2_fourcc(a, b, c, d) | (1U << 31))
@@ -260,6 +255,7 @@
#define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ')
#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B')
#define V4L2_PIX_FMT_Y10P v4l2_fourcc('Y', '1', '0', 'P')
+#define V4L2_PIX_FMT_IPU3_Y10 v4l2_fourcc('i', 'p', '3', 'y')
#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8')
#define V4L2_PIX_FMT_UV8 v4l2_fourcc('U', 'V', '8', ' ')
#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V')
@@ -277,6 +273,8 @@
#define V4L2_PIX_FMT_XYUV32 v4l2_fourcc('X', 'Y', 'U', 'V')
#define V4L2_PIX_FMT_VUYA32 v4l2_fourcc('V', 'U', 'Y', 'A')
#define V4L2_PIX_FMT_VUYX32 v4l2_fourcc('V', 'U', 'Y', 'X')
+#define V4L2_PIX_FMT_YUVA32 v4l2_fourcc('Y', 'U', 'V', 'A')
+#define V4L2_PIX_FMT_YUVX32 v4l2_fourcc('Y', 'U', 'V', 'X')
#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0')
#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2')
#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1')
@@ -284,6 +282,7 @@
#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1')
#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4')
#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2')
+#define V4L2_PIX_FMT_P010 v4l2_fourcc('P', '0', '1', '0')
#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2')
#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1')
#define V4L2_PIX_FMT_NV16M v4l2_fourcc('N', 'M', '1', '6')
@@ -303,8 +302,11 @@
#define V4L2_PIX_FMT_NV12_4L4 v4l2_fourcc('V', 'T', '1', '2')
#define V4L2_PIX_FMT_NV12_16L16 v4l2_fourcc('H', 'M', '1', '2')
#define V4L2_PIX_FMT_NV12_32L32 v4l2_fourcc('S', 'T', '1', '2')
+#define V4L2_PIX_FMT_P010_4L4 v4l2_fourcc('T', '0', '1', '0')
#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2')
#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2')
+#define V4L2_PIX_FMT_NV12M_8L128 v4l2_fourcc('N', 'A', '1', '2')
+#define V4L2_PIX_FMT_NV12M_10BE_8L128 v4l2_fourcc_be('N', 'T', '1', '2')
#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1')
#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G')
#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G')
@@ -370,6 +372,7 @@
#define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T')
#define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H')
#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4')
+#define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5')
#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A')
#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A')
#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0')
@@ -404,6 +407,8 @@
#define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I')
#define V4L2_PIX_FMT_CNF4 v4l2_fourcc('C', 'N', 'F', '4')
#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4')
+#define V4L2_PIX_FMT_QC08C v4l2_fourcc('Q', '0', '8', 'C')
+#define V4L2_PIX_FMT_QC10C v4l2_fourcc('Q', '1', '0', 'C')
#define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b')
#define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g')
#define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G')
@@ -906,6 +911,11 @@
struct v4l2_ctrl_mpeg2_quantisation __user * p_mpeg2_quantisation;
struct v4l2_ctrl_vp9_compressed_hdr __user * p_vp9_compressed_hdr_probs;
struct v4l2_ctrl_vp9_frame __user * p_vp9_frame;
+ struct v4l2_ctrl_hevc_sps __user * p_hevc_sps;
+ struct v4l2_ctrl_hevc_pps __user * p_hevc_pps;
+ struct v4l2_ctrl_hevc_slice_params __user * p_hevc_slice_params;
+ struct v4l2_ctrl_hevc_scaling_matrix __user * p_hevc_scaling_matrix;
+ struct v4l2_ctrl_hevc_decode_params __user * p_hevc_decode_params;
void __user * ptr;
};
} __attribute__((packed));
@@ -958,6 +968,11 @@
V4L2_CTRL_TYPE_MPEG2_PICTURE = 0x0252,
V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR = 0x0260,
V4L2_CTRL_TYPE_VP9_FRAME = 0x0261,
+ V4L2_CTRL_TYPE_HEVC_SPS = 0x0270,
+ V4L2_CTRL_TYPE_HEVC_PPS = 0x0271,
+ V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS = 0x0272,
+ V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX = 0x0273,
+ V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS = 0x0274,
};
struct v4l2_queryctrl {
__u32 id;
@@ -1005,6 +1020,7 @@
#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_DYNAMIC_ARRAY 0x0800
#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
#define V4L2_CTRL_FLAG_NEXT_COMPOUND 0x40000000
#define V4L2_CID_MAX_CTRLS 1024
diff --git a/libc/kernel/uapi/linux/virtio_9p.h b/libc/kernel/uapi/linux/virtio_9p.h
index 1d9dfb1..2e05786 100644
--- a/libc/kernel/uapi/linux/virtio_9p.h
+++ b/libc/kernel/uapi/linux/virtio_9p.h
@@ -24,6 +24,6 @@
#define VIRTIO_9P_MOUNT_TAG 0
struct virtio_9p_config {
__virtio16 tag_len;
- __u8 tag[0];
+ __u8 tag[];
} __attribute__((packed));
#endif
diff --git a/libc/kernel/uapi/linux/virtio_config.h b/libc/kernel/uapi/linux/virtio_config.h
index 6198fd1..bdd2e73 100644
--- a/libc/kernel/uapi/linux/virtio_config.h
+++ b/libc/kernel/uapi/linux/virtio_config.h
@@ -26,7 +26,7 @@
#define VIRTIO_CONFIG_S_NEEDS_RESET 0x40
#define VIRTIO_CONFIG_S_FAILED 0x80
#define VIRTIO_TRANSPORT_F_START 28
-#define VIRTIO_TRANSPORT_F_END 38
+#define VIRTIO_TRANSPORT_F_END 41
#ifndef VIRTIO_CONFIG_NO_LEGACY
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
#define VIRTIO_F_ANY_LAYOUT 27
@@ -35,6 +35,8 @@
#define VIRTIO_F_ACCESS_PLATFORM 33
#define VIRTIO_F_IOMMU_PLATFORM VIRTIO_F_ACCESS_PLATFORM
#define VIRTIO_F_RING_PACKED 34
+#define VIRTIO_F_IN_ORDER 35
#define VIRTIO_F_ORDER_PLATFORM 36
#define VIRTIO_F_SR_IOV 37
+#define VIRTIO_F_RING_RESET 40
#endif
diff --git a/libc/kernel/uapi/linux/virtio_crypto.h b/libc/kernel/uapi/linux/virtio_crypto.h
index 2ce760f..7d7561d 100644
--- a/libc/kernel/uapi/linux/virtio_crypto.h
+++ b/libc/kernel/uapi/linux/virtio_crypto.h
@@ -26,6 +26,7 @@
#define VIRTIO_CRYPTO_SERVICE_HASH 1
#define VIRTIO_CRYPTO_SERVICE_MAC 2
#define VIRTIO_CRYPTO_SERVICE_AEAD 3
+#define VIRTIO_CRYPTO_SERVICE_AKCIPHER 4
#define VIRTIO_CRYPTO_OPCODE(service,op) (((service) << 8) | (op))
struct virtio_crypto_ctrl_header {
#define VIRTIO_CRYPTO_CIPHER_CREATE_SESSION VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x02)
@@ -36,6 +37,8 @@
#define VIRTIO_CRYPTO_MAC_DESTROY_SESSION VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x03)
#define VIRTIO_CRYPTO_AEAD_CREATE_SESSION VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x02)
#define VIRTIO_CRYPTO_AEAD_DESTROY_SESSION VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x03)
+#define VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x04)
+#define VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x05)
__le32 opcode;
__le32 algo;
__le32 flag;
@@ -137,6 +140,51 @@
struct virtio_crypto_aead_session_para para;
__u8 padding[32];
};
+struct virtio_crypto_rsa_session_para {
+#define VIRTIO_CRYPTO_RSA_RAW_PADDING 0
+#define VIRTIO_CRYPTO_RSA_PKCS1_PADDING 1
+ __le32 padding_algo;
+#define VIRTIO_CRYPTO_RSA_NO_HASH 0
+#define VIRTIO_CRYPTO_RSA_MD2 1
+#define VIRTIO_CRYPTO_RSA_MD3 2
+#define VIRTIO_CRYPTO_RSA_MD4 3
+#define VIRTIO_CRYPTO_RSA_MD5 4
+#define VIRTIO_CRYPTO_RSA_SHA1 5
+#define VIRTIO_CRYPTO_RSA_SHA256 6
+#define VIRTIO_CRYPTO_RSA_SHA384 7
+#define VIRTIO_CRYPTO_RSA_SHA512 8
+#define VIRTIO_CRYPTO_RSA_SHA224 9
+ __le32 hash_algo;
+};
+struct virtio_crypto_ecdsa_session_para {
+#define VIRTIO_CRYPTO_CURVE_UNKNOWN 0
+#define VIRTIO_CRYPTO_CURVE_NIST_P192 1
+#define VIRTIO_CRYPTO_CURVE_NIST_P224 2
+#define VIRTIO_CRYPTO_CURVE_NIST_P256 3
+#define VIRTIO_CRYPTO_CURVE_NIST_P384 4
+#define VIRTIO_CRYPTO_CURVE_NIST_P521 5
+ __le32 curve_id;
+ __le32 padding;
+};
+struct virtio_crypto_akcipher_session_para {
+#define VIRTIO_CRYPTO_NO_AKCIPHER 0
+#define VIRTIO_CRYPTO_AKCIPHER_RSA 1
+#define VIRTIO_CRYPTO_AKCIPHER_DSA 2
+#define VIRTIO_CRYPTO_AKCIPHER_ECDSA 3
+ __le32 algo;
+#define VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC 1
+#define VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE 2
+ __le32 keytype;
+ __le32 keylen;
+ union {
+ struct virtio_crypto_rsa_session_para rsa;
+ struct virtio_crypto_ecdsa_session_para ecdsa;
+ } u;
+};
+struct virtio_crypto_akcipher_create_session_req {
+ struct virtio_crypto_akcipher_session_para para;
+ __u8 padding[36];
+};
struct virtio_crypto_alg_chain_session_para {
#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER 1
#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH 2
@@ -180,6 +228,7 @@
struct virtio_crypto_hash_create_session_req hash_create_session;
struct virtio_crypto_mac_create_session_req mac_create_session;
struct virtio_crypto_aead_create_session_req aead_create_session;
+ struct virtio_crypto_akcipher_create_session_req akcipher_create_session;
struct virtio_crypto_destroy_session_req destroy_session;
__u8 padding[56];
} u;
@@ -191,6 +240,10 @@
#define VIRTIO_CRYPTO_MAC VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x00)
#define VIRTIO_CRYPTO_AEAD_ENCRYPT VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x00)
#define VIRTIO_CRYPTO_AEAD_DECRYPT VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x01)
+#define VIRTIO_CRYPTO_AKCIPHER_ENCRYPT VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x00)
+#define VIRTIO_CRYPTO_AKCIPHER_DECRYPT VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x01)
+#define VIRTIO_CRYPTO_AKCIPHER_SIGN VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x02)
+#define VIRTIO_CRYPTO_AKCIPHER_VERIFY VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x03)
__le32 opcode;
__le32 algo;
__le64 session_id;
@@ -256,6 +309,14 @@
struct virtio_crypto_aead_para para;
__u8 padding[32];
};
+struct virtio_crypto_akcipher_para {
+ __le32 src_data_len;
+ __le32 dst_data_len;
+};
+struct virtio_crypto_akcipher_data_req {
+ struct virtio_crypto_akcipher_para para;
+ __u8 padding[40];
+};
struct virtio_crypto_op_data_req {
struct virtio_crypto_op_header header;
union {
@@ -263,6 +324,7 @@
struct virtio_crypto_hash_data_req hash_req;
struct virtio_crypto_mac_data_req mac_req;
struct virtio_crypto_aead_data_req aead_req;
+ struct virtio_crypto_akcipher_data_req akcipher_req;
__u8 padding[48];
} u;
};
@@ -271,6 +333,8 @@
#define VIRTIO_CRYPTO_BADMSG 2
#define VIRTIO_CRYPTO_NOTSUPP 3
#define VIRTIO_CRYPTO_INVSESS 4
+#define VIRTIO_CRYPTO_NOSPC 5
+#define VIRTIO_CRYPTO_KEY_REJECTED 6
#define VIRTIO_CRYPTO_S_HW_READY (1 << 0)
struct virtio_crypto_config {
__le32 status;
@@ -284,7 +348,7 @@
__le32 aead_algo;
__le32 max_cipher_key_len;
__le32 max_auth_key_len;
- __le32 reserve;
+ __le32 akcipher_algo;
__le64 max_size;
};
struct virtio_crypto_inhdr {
diff --git a/libc/kernel/uapi/linux/virtio_ids.h b/libc/kernel/uapi/linux/virtio_ids.h
index 2894700..b31ed93 100644
--- a/libc/kernel/uapi/linux/virtio_ids.h
+++ b/libc/kernel/uapi/linux/virtio_ids.h
@@ -57,11 +57,11 @@
#define VIRTIO_ID_AUDIO_POLICY 39
#define VIRTIO_ID_BT 40
#define VIRTIO_ID_GPIO 41
-#define VIRTIO_TRANS_ID_NET 1000
-#define VIRTIO_TRANS_ID_BLOCK 1001
-#define VIRTIO_TRANS_ID_BALLOON 1002
-#define VIRTIO_TRANS_ID_CONSOLE 1003
-#define VIRTIO_TRANS_ID_SCSI 1004
-#define VIRTIO_TRANS_ID_RNG 1005
-#define VIRTIO_TRANS_ID_9P 1009
+#define VIRTIO_TRANS_ID_NET 0x1000
+#define VIRTIO_TRANS_ID_BLOCK 0x1001
+#define VIRTIO_TRANS_ID_BALLOON 0x1002
+#define VIRTIO_TRANS_ID_CONSOLE 0x1003
+#define VIRTIO_TRANS_ID_SCSI 0x1004
+#define VIRTIO_TRANS_ID_RNG 0x1005
+#define VIRTIO_TRANS_ID_9P 0x1009
#endif
diff --git a/libc/kernel/uapi/linux/virtio_net.h b/libc/kernel/uapi/linux/virtio_net.h
index 2d92904..6fe90aa 100644
--- a/libc/kernel/uapi/linux/virtio_net.h
+++ b/libc/kernel/uapi/linux/virtio_net.h
@@ -45,6 +45,7 @@
#define VIRTIO_NET_F_GUEST_ANNOUNCE 21
#define VIRTIO_NET_F_MQ 22
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23
+#define VIRTIO_NET_F_NOTF_COAL 53
#define VIRTIO_NET_F_HASH_REPORT 57
#define VIRTIO_NET_F_RSS 60
#define VIRTIO_NET_F_RSC_EXT 61
@@ -186,4 +187,15 @@
#define VIRTIO_NET_CTRL_MQ_HASH_CONFIG 2
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
+#define VIRTIO_NET_CTRL_NOTF_COAL 6
+struct virtio_net_ctrl_coal_tx {
+ __le32 tx_max_packets;
+ __le32 tx_usecs;
+};
+#define VIRTIO_NET_CTRL_NOTF_COAL_TX_SET 0
+struct virtio_net_ctrl_coal_rx {
+ __le32 rx_max_packets;
+ __le32 rx_usecs;
+};
+#define VIRTIO_NET_CTRL_NOTF_COAL_RX_SET 1
#endif
diff --git a/libc/kernel/uapi/linux/virtio_pci.h b/libc/kernel/uapi/linux/virtio_pci.h
index e6d2731..94ca0a2 100644
--- a/libc/kernel/uapi/linux/virtio_pci.h
+++ b/libc/kernel/uapi/linux/virtio_pci.h
@@ -117,5 +117,7 @@
#define VIRTIO_PCI_COMMON_Q_AVAILHI 44
#define VIRTIO_PCI_COMMON_Q_USEDLO 48
#define VIRTIO_PCI_COMMON_Q_USEDHI 52
+#define VIRTIO_PCI_COMMON_Q_NDATA 56
+#define VIRTIO_PCI_COMMON_Q_RESET 58
#endif
#endif
diff --git a/libc/kernel/uapi/linux/xfrm.h b/libc/kernel/uapi/linux/xfrm.h
index f4df95f..77ded42 100644
--- a/libc/kernel/uapi/linux/xfrm.h
+++ b/libc/kernel/uapi/linux/xfrm.h
@@ -35,7 +35,7 @@
__u8 ctx_alg;
__u16 ctx_len;
__u32 ctx_sid;
- char ctx_str[0];
+ char ctx_str[];
};
#define XFRM_SC_DOI_RESERVED 0
#define XFRM_SC_DOI_LSM 1
@@ -85,24 +85,24 @@
__u32 oseq_hi;
__u32 seq_hi;
__u32 replay_window;
- __u32 bmp[0];
+ __u32 bmp[];
};
struct xfrm_algo {
char alg_name[64];
unsigned int alg_key_len;
- char alg_key[0];
+ char alg_key[];
};
struct xfrm_algo_auth {
char alg_name[64];
unsigned int alg_key_len;
unsigned int alg_trunc_len;
- char alg_key[0];
+ char alg_key[];
};
struct xfrm_algo_aead {
char alg_name[64];
unsigned int alg_key_len;
unsigned int alg_icv_len;
- char alg_key[0];
+ char alg_key[];
};
struct xfrm_stats {
__u32 replay_window;
diff --git a/libc/kernel/uapi/misc/fastrpc.h b/libc/kernel/uapi/misc/fastrpc.h
index 62955ec..e82b961 100644
--- a/libc/kernel/uapi/misc/fastrpc.h
+++ b/libc/kernel/uapi/misc/fastrpc.h
@@ -27,11 +27,32 @@
#define FASTRPC_IOCTL_MMAP _IOWR('R', 6, struct fastrpc_req_mmap)
#define FASTRPC_IOCTL_MUNMAP _IOWR('R', 7, struct fastrpc_req_munmap)
#define FASTRPC_IOCTL_INIT_ATTACH_SNS _IO('R', 8)
+#define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map)
+#define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap)
+#define FASTRPC_IOCTL_GET_DSP_INFO _IOWR('R', 13, struct fastrpc_ioctl_capability)
+enum fastrpc_map_flags {
+ FASTRPC_MAP_STATIC = 0,
+ FASTRPC_MAP_RESERVED,
+ FASTRPC_MAP_FD = 2,
+ FASTRPC_MAP_FD_DELAYED,
+ FASTRPC_MAP_FD_NOMAP = 16,
+ FASTRPC_MAP_MAX,
+};
+enum fastrpc_proc_attr {
+ FASTRPC_MODE_DEBUG = (1 << 0),
+ FASTRPC_MODE_PTRACE = (1 << 1),
+ FASTRPC_MODE_CRC = (1 << 2),
+ FASTRPC_MODE_UNSIGNED_MODULE = (1 << 3),
+ FASTRPC_MODE_ADAPTIVE_QOS = (1 << 4),
+ FASTRPC_MODE_SYSTEM_PROCESS = (1 << 5),
+ FASTRPC_MODE_PRIVILEGED = (1 << 6),
+};
+#define FASTRPC_ATTR_SECUREMAP (1)
struct fastrpc_invoke_args {
__u64 ptr;
__u64 length;
__s32 fd;
- __u32 reserved;
+ __u32 attr;
};
struct fastrpc_invoke {
__u32 handle;
@@ -57,8 +78,32 @@
__u64 size;
__u64 vaddrout;
};
+struct fastrpc_mem_map {
+ __s32 version;
+ __s32 fd;
+ __s32 offset;
+ __u32 flags;
+ __u64 vaddrin;
+ __u64 length;
+ __u64 vaddrout;
+ __s32 attrs;
+ __s32 reserved[4];
+};
struct fastrpc_req_munmap {
__u64 vaddrout;
__u64 size;
};
+struct fastrpc_mem_unmap {
+ __s32 vesion;
+ __s32 fd;
+ __u64 vaddr;
+ __u64 length;
+ __s32 reserved[5];
+};
+struct fastrpc_ioctl_capability {
+ __u32 domain;
+ __u32 attribute_id;
+ __u32 capability;
+ __u32 reserved[4];
+};
#endif
diff --git a/libc/kernel/uapi/misc/habanalabs.h b/libc/kernel/uapi/misc/habanalabs.h
index 6e3439a..6703676 100644
--- a/libc/kernel/uapi/misc/habanalabs.h
+++ b/libc/kernel/uapi/misc/habanalabs.h
@@ -24,6 +24,7 @@
#define GAUDI_DRIVER_SRAM_RESERVED_SIZE_FROM_START 0x80
#define GAUDI_FIRST_AVAILABLE_W_S_SYNC_OBJECT 144
#define GAUDI_FIRST_AVAILABLE_W_S_MONITOR 72
+#define TS_MAX_ELEMENTS_NUM (1 << 20)
enum goya_queue_id {
GOYA_QUEUE_ID_DMA_0 = 0,
GOYA_QUEUE_ID_DMA_1 = 1,
@@ -158,6 +159,270 @@
GAUDI_QUEUE_ID_NIC_9_3 = 112,
GAUDI_QUEUE_ID_SIZE
};
+enum gaudi2_queue_id {
+ GAUDI2_QUEUE_ID_PDMA_0_0 = 0,
+ GAUDI2_QUEUE_ID_PDMA_0_1 = 1,
+ GAUDI2_QUEUE_ID_PDMA_0_2 = 2,
+ GAUDI2_QUEUE_ID_PDMA_0_3 = 3,
+ GAUDI2_QUEUE_ID_PDMA_1_0 = 4,
+ GAUDI2_QUEUE_ID_PDMA_1_1 = 5,
+ GAUDI2_QUEUE_ID_PDMA_1_2 = 6,
+ GAUDI2_QUEUE_ID_PDMA_1_3 = 7,
+ GAUDI2_QUEUE_ID_DCORE0_EDMA_0_0 = 8,
+ GAUDI2_QUEUE_ID_DCORE0_EDMA_0_1 = 9,
+ GAUDI2_QUEUE_ID_DCORE0_EDMA_0_2 = 10,
+ GAUDI2_QUEUE_ID_DCORE0_EDMA_0_3 = 11,
+ GAUDI2_QUEUE_ID_DCORE0_EDMA_1_0 = 12,
+ GAUDI2_QUEUE_ID_DCORE0_EDMA_1_1 = 13,
+ GAUDI2_QUEUE_ID_DCORE0_EDMA_1_2 = 14,
+ GAUDI2_QUEUE_ID_DCORE0_EDMA_1_3 = 15,
+ GAUDI2_QUEUE_ID_DCORE0_MME_0_0 = 16,
+ GAUDI2_QUEUE_ID_DCORE0_MME_0_1 = 17,
+ GAUDI2_QUEUE_ID_DCORE0_MME_0_2 = 18,
+ GAUDI2_QUEUE_ID_DCORE0_MME_0_3 = 19,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_0_0 = 20,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_0_1 = 21,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_0_2 = 22,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_0_3 = 23,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_1_0 = 24,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_1_1 = 25,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_1_2 = 26,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_1_3 = 27,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_2_0 = 28,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_2_1 = 29,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_2_2 = 30,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_2_3 = 31,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_3_0 = 32,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_3_1 = 33,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_3_2 = 34,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_3_3 = 35,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_4_0 = 36,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_4_1 = 37,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_4_2 = 38,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_4_3 = 39,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_5_0 = 40,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_5_1 = 41,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_5_2 = 42,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_5_3 = 43,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_6_0 = 44,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_6_1 = 45,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_6_2 = 46,
+ GAUDI2_QUEUE_ID_DCORE0_TPC_6_3 = 47,
+ GAUDI2_QUEUE_ID_DCORE1_EDMA_0_0 = 48,
+ GAUDI2_QUEUE_ID_DCORE1_EDMA_0_1 = 49,
+ GAUDI2_QUEUE_ID_DCORE1_EDMA_0_2 = 50,
+ GAUDI2_QUEUE_ID_DCORE1_EDMA_0_3 = 51,
+ GAUDI2_QUEUE_ID_DCORE1_EDMA_1_0 = 52,
+ GAUDI2_QUEUE_ID_DCORE1_EDMA_1_1 = 53,
+ GAUDI2_QUEUE_ID_DCORE1_EDMA_1_2 = 54,
+ GAUDI2_QUEUE_ID_DCORE1_EDMA_1_3 = 55,
+ GAUDI2_QUEUE_ID_DCORE1_MME_0_0 = 56,
+ GAUDI2_QUEUE_ID_DCORE1_MME_0_1 = 57,
+ GAUDI2_QUEUE_ID_DCORE1_MME_0_2 = 58,
+ GAUDI2_QUEUE_ID_DCORE1_MME_0_3 = 59,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_0_0 = 60,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_0_1 = 61,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_0_2 = 62,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_0_3 = 63,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_1_0 = 64,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_1_1 = 65,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_1_2 = 66,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_1_3 = 67,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_2_0 = 68,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_2_1 = 69,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_2_2 = 70,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_2_3 = 71,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_3_0 = 72,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_3_1 = 73,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_3_2 = 74,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_3_3 = 75,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_4_0 = 76,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_4_1 = 77,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_4_2 = 78,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_4_3 = 79,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_5_0 = 80,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_5_1 = 81,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_5_2 = 82,
+ GAUDI2_QUEUE_ID_DCORE1_TPC_5_3 = 83,
+ GAUDI2_QUEUE_ID_DCORE2_EDMA_0_0 = 84,
+ GAUDI2_QUEUE_ID_DCORE2_EDMA_0_1 = 85,
+ GAUDI2_QUEUE_ID_DCORE2_EDMA_0_2 = 86,
+ GAUDI2_QUEUE_ID_DCORE2_EDMA_0_3 = 87,
+ GAUDI2_QUEUE_ID_DCORE2_EDMA_1_0 = 88,
+ GAUDI2_QUEUE_ID_DCORE2_EDMA_1_1 = 89,
+ GAUDI2_QUEUE_ID_DCORE2_EDMA_1_2 = 90,
+ GAUDI2_QUEUE_ID_DCORE2_EDMA_1_3 = 91,
+ GAUDI2_QUEUE_ID_DCORE2_MME_0_0 = 92,
+ GAUDI2_QUEUE_ID_DCORE2_MME_0_1 = 93,
+ GAUDI2_QUEUE_ID_DCORE2_MME_0_2 = 94,
+ GAUDI2_QUEUE_ID_DCORE2_MME_0_3 = 95,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_0_0 = 96,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_0_1 = 97,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_0_2 = 98,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_0_3 = 99,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_1_0 = 100,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_1_1 = 101,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_1_2 = 102,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_1_3 = 103,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_2_0 = 104,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_2_1 = 105,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_2_2 = 106,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_2_3 = 107,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_3_0 = 108,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_3_1 = 109,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_3_2 = 110,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_3_3 = 111,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_4_0 = 112,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_4_1 = 113,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_4_2 = 114,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_4_3 = 115,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_5_0 = 116,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_5_1 = 117,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_5_2 = 118,
+ GAUDI2_QUEUE_ID_DCORE2_TPC_5_3 = 119,
+ GAUDI2_QUEUE_ID_DCORE3_EDMA_0_0 = 120,
+ GAUDI2_QUEUE_ID_DCORE3_EDMA_0_1 = 121,
+ GAUDI2_QUEUE_ID_DCORE3_EDMA_0_2 = 122,
+ GAUDI2_QUEUE_ID_DCORE3_EDMA_0_3 = 123,
+ GAUDI2_QUEUE_ID_DCORE3_EDMA_1_0 = 124,
+ GAUDI2_QUEUE_ID_DCORE3_EDMA_1_1 = 125,
+ GAUDI2_QUEUE_ID_DCORE3_EDMA_1_2 = 126,
+ GAUDI2_QUEUE_ID_DCORE3_EDMA_1_3 = 127,
+ GAUDI2_QUEUE_ID_DCORE3_MME_0_0 = 128,
+ GAUDI2_QUEUE_ID_DCORE3_MME_0_1 = 129,
+ GAUDI2_QUEUE_ID_DCORE3_MME_0_2 = 130,
+ GAUDI2_QUEUE_ID_DCORE3_MME_0_3 = 131,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_0_0 = 132,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_0_1 = 133,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_0_2 = 134,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_0_3 = 135,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_1_0 = 136,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_1_1 = 137,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_1_2 = 138,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_1_3 = 139,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_2_0 = 140,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_2_1 = 141,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_2_2 = 142,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_2_3 = 143,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_3_0 = 144,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_3_1 = 145,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_3_2 = 146,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_3_3 = 147,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_4_0 = 148,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_4_1 = 149,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_4_2 = 150,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_4_3 = 151,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_5_0 = 152,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_5_1 = 153,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_5_2 = 154,
+ GAUDI2_QUEUE_ID_DCORE3_TPC_5_3 = 155,
+ GAUDI2_QUEUE_ID_NIC_0_0 = 156,
+ GAUDI2_QUEUE_ID_NIC_0_1 = 157,
+ GAUDI2_QUEUE_ID_NIC_0_2 = 158,
+ GAUDI2_QUEUE_ID_NIC_0_3 = 159,
+ GAUDI2_QUEUE_ID_NIC_1_0 = 160,
+ GAUDI2_QUEUE_ID_NIC_1_1 = 161,
+ GAUDI2_QUEUE_ID_NIC_1_2 = 162,
+ GAUDI2_QUEUE_ID_NIC_1_3 = 163,
+ GAUDI2_QUEUE_ID_NIC_2_0 = 164,
+ GAUDI2_QUEUE_ID_NIC_2_1 = 165,
+ GAUDI2_QUEUE_ID_NIC_2_2 = 166,
+ GAUDI2_QUEUE_ID_NIC_2_3 = 167,
+ GAUDI2_QUEUE_ID_NIC_3_0 = 168,
+ GAUDI2_QUEUE_ID_NIC_3_1 = 169,
+ GAUDI2_QUEUE_ID_NIC_3_2 = 170,
+ GAUDI2_QUEUE_ID_NIC_3_3 = 171,
+ GAUDI2_QUEUE_ID_NIC_4_0 = 172,
+ GAUDI2_QUEUE_ID_NIC_4_1 = 173,
+ GAUDI2_QUEUE_ID_NIC_4_2 = 174,
+ GAUDI2_QUEUE_ID_NIC_4_3 = 175,
+ GAUDI2_QUEUE_ID_NIC_5_0 = 176,
+ GAUDI2_QUEUE_ID_NIC_5_1 = 177,
+ GAUDI2_QUEUE_ID_NIC_5_2 = 178,
+ GAUDI2_QUEUE_ID_NIC_5_3 = 179,
+ GAUDI2_QUEUE_ID_NIC_6_0 = 180,
+ GAUDI2_QUEUE_ID_NIC_6_1 = 181,
+ GAUDI2_QUEUE_ID_NIC_6_2 = 182,
+ GAUDI2_QUEUE_ID_NIC_6_3 = 183,
+ GAUDI2_QUEUE_ID_NIC_7_0 = 184,
+ GAUDI2_QUEUE_ID_NIC_7_1 = 185,
+ GAUDI2_QUEUE_ID_NIC_7_2 = 186,
+ GAUDI2_QUEUE_ID_NIC_7_3 = 187,
+ GAUDI2_QUEUE_ID_NIC_8_0 = 188,
+ GAUDI2_QUEUE_ID_NIC_8_1 = 189,
+ GAUDI2_QUEUE_ID_NIC_8_2 = 190,
+ GAUDI2_QUEUE_ID_NIC_8_3 = 191,
+ GAUDI2_QUEUE_ID_NIC_9_0 = 192,
+ GAUDI2_QUEUE_ID_NIC_9_1 = 193,
+ GAUDI2_QUEUE_ID_NIC_9_2 = 194,
+ GAUDI2_QUEUE_ID_NIC_9_3 = 195,
+ GAUDI2_QUEUE_ID_NIC_10_0 = 196,
+ GAUDI2_QUEUE_ID_NIC_10_1 = 197,
+ GAUDI2_QUEUE_ID_NIC_10_2 = 198,
+ GAUDI2_QUEUE_ID_NIC_10_3 = 199,
+ GAUDI2_QUEUE_ID_NIC_11_0 = 200,
+ GAUDI2_QUEUE_ID_NIC_11_1 = 201,
+ GAUDI2_QUEUE_ID_NIC_11_2 = 202,
+ GAUDI2_QUEUE_ID_NIC_11_3 = 203,
+ GAUDI2_QUEUE_ID_NIC_12_0 = 204,
+ GAUDI2_QUEUE_ID_NIC_12_1 = 205,
+ GAUDI2_QUEUE_ID_NIC_12_2 = 206,
+ GAUDI2_QUEUE_ID_NIC_12_3 = 207,
+ GAUDI2_QUEUE_ID_NIC_13_0 = 208,
+ GAUDI2_QUEUE_ID_NIC_13_1 = 209,
+ GAUDI2_QUEUE_ID_NIC_13_2 = 210,
+ GAUDI2_QUEUE_ID_NIC_13_3 = 211,
+ GAUDI2_QUEUE_ID_NIC_14_0 = 212,
+ GAUDI2_QUEUE_ID_NIC_14_1 = 213,
+ GAUDI2_QUEUE_ID_NIC_14_2 = 214,
+ GAUDI2_QUEUE_ID_NIC_14_3 = 215,
+ GAUDI2_QUEUE_ID_NIC_15_0 = 216,
+ GAUDI2_QUEUE_ID_NIC_15_1 = 217,
+ GAUDI2_QUEUE_ID_NIC_15_2 = 218,
+ GAUDI2_QUEUE_ID_NIC_15_3 = 219,
+ GAUDI2_QUEUE_ID_NIC_16_0 = 220,
+ GAUDI2_QUEUE_ID_NIC_16_1 = 221,
+ GAUDI2_QUEUE_ID_NIC_16_2 = 222,
+ GAUDI2_QUEUE_ID_NIC_16_3 = 223,
+ GAUDI2_QUEUE_ID_NIC_17_0 = 224,
+ GAUDI2_QUEUE_ID_NIC_17_1 = 225,
+ GAUDI2_QUEUE_ID_NIC_17_2 = 226,
+ GAUDI2_QUEUE_ID_NIC_17_3 = 227,
+ GAUDI2_QUEUE_ID_NIC_18_0 = 228,
+ GAUDI2_QUEUE_ID_NIC_18_1 = 229,
+ GAUDI2_QUEUE_ID_NIC_18_2 = 230,
+ GAUDI2_QUEUE_ID_NIC_18_3 = 231,
+ GAUDI2_QUEUE_ID_NIC_19_0 = 232,
+ GAUDI2_QUEUE_ID_NIC_19_1 = 233,
+ GAUDI2_QUEUE_ID_NIC_19_2 = 234,
+ GAUDI2_QUEUE_ID_NIC_19_3 = 235,
+ GAUDI2_QUEUE_ID_NIC_20_0 = 236,
+ GAUDI2_QUEUE_ID_NIC_20_1 = 237,
+ GAUDI2_QUEUE_ID_NIC_20_2 = 238,
+ GAUDI2_QUEUE_ID_NIC_20_3 = 239,
+ GAUDI2_QUEUE_ID_NIC_21_0 = 240,
+ GAUDI2_QUEUE_ID_NIC_21_1 = 241,
+ GAUDI2_QUEUE_ID_NIC_21_2 = 242,
+ GAUDI2_QUEUE_ID_NIC_21_3 = 243,
+ GAUDI2_QUEUE_ID_NIC_22_0 = 244,
+ GAUDI2_QUEUE_ID_NIC_22_1 = 245,
+ GAUDI2_QUEUE_ID_NIC_22_2 = 246,
+ GAUDI2_QUEUE_ID_NIC_22_3 = 247,
+ GAUDI2_QUEUE_ID_NIC_23_0 = 248,
+ GAUDI2_QUEUE_ID_NIC_23_1 = 249,
+ GAUDI2_QUEUE_ID_NIC_23_2 = 250,
+ GAUDI2_QUEUE_ID_NIC_23_3 = 251,
+ GAUDI2_QUEUE_ID_ROT_0_0 = 252,
+ GAUDI2_QUEUE_ID_ROT_0_1 = 253,
+ GAUDI2_QUEUE_ID_ROT_0_2 = 254,
+ GAUDI2_QUEUE_ID_ROT_0_3 = 255,
+ GAUDI2_QUEUE_ID_ROT_1_0 = 256,
+ GAUDI2_QUEUE_ID_ROT_1_1 = 257,
+ GAUDI2_QUEUE_ID_ROT_1_2 = 258,
+ GAUDI2_QUEUE_ID_ROT_1_3 = 259,
+ GAUDI2_QUEUE_ID_CPU_PQ = 260,
+ GAUDI2_QUEUE_ID_SIZE
+};
enum goya_engine_id {
GOYA_ENGINE_ID_DMA_0 = 0,
GOYA_ENGINE_ID_DMA_1,
@@ -208,6 +473,84 @@
GAUDI_ENGINE_ID_NIC_9,
GAUDI_ENGINE_ID_SIZE
};
+enum gaudi2_engine_id {
+ GAUDI2_DCORE0_ENGINE_ID_EDMA_0 = 0,
+ GAUDI2_DCORE0_ENGINE_ID_EDMA_1,
+ GAUDI2_DCORE0_ENGINE_ID_MME,
+ GAUDI2_DCORE0_ENGINE_ID_TPC_0,
+ GAUDI2_DCORE0_ENGINE_ID_TPC_1,
+ GAUDI2_DCORE0_ENGINE_ID_TPC_2,
+ GAUDI2_DCORE0_ENGINE_ID_TPC_3,
+ GAUDI2_DCORE0_ENGINE_ID_TPC_4,
+ GAUDI2_DCORE0_ENGINE_ID_TPC_5,
+ GAUDI2_DCORE0_ENGINE_ID_DEC_0,
+ GAUDI2_DCORE0_ENGINE_ID_DEC_1,
+ GAUDI2_DCORE1_ENGINE_ID_EDMA_0,
+ GAUDI2_DCORE1_ENGINE_ID_EDMA_1,
+ GAUDI2_DCORE1_ENGINE_ID_MME,
+ GAUDI2_DCORE1_ENGINE_ID_TPC_0,
+ GAUDI2_DCORE1_ENGINE_ID_TPC_1,
+ GAUDI2_DCORE1_ENGINE_ID_TPC_2,
+ GAUDI2_DCORE1_ENGINE_ID_TPC_3,
+ GAUDI2_DCORE1_ENGINE_ID_TPC_4,
+ GAUDI2_DCORE1_ENGINE_ID_TPC_5,
+ GAUDI2_DCORE1_ENGINE_ID_DEC_0,
+ GAUDI2_DCORE1_ENGINE_ID_DEC_1,
+ GAUDI2_DCORE2_ENGINE_ID_EDMA_0,
+ GAUDI2_DCORE2_ENGINE_ID_EDMA_1,
+ GAUDI2_DCORE2_ENGINE_ID_MME,
+ GAUDI2_DCORE2_ENGINE_ID_TPC_0,
+ GAUDI2_DCORE2_ENGINE_ID_TPC_1,
+ GAUDI2_DCORE2_ENGINE_ID_TPC_2,
+ GAUDI2_DCORE2_ENGINE_ID_TPC_3,
+ GAUDI2_DCORE2_ENGINE_ID_TPC_4,
+ GAUDI2_DCORE2_ENGINE_ID_TPC_5,
+ GAUDI2_DCORE2_ENGINE_ID_DEC_0,
+ GAUDI2_DCORE2_ENGINE_ID_DEC_1,
+ GAUDI2_DCORE3_ENGINE_ID_EDMA_0,
+ GAUDI2_DCORE3_ENGINE_ID_EDMA_1,
+ GAUDI2_DCORE3_ENGINE_ID_MME,
+ GAUDI2_DCORE3_ENGINE_ID_TPC_0,
+ GAUDI2_DCORE3_ENGINE_ID_TPC_1,
+ GAUDI2_DCORE3_ENGINE_ID_TPC_2,
+ GAUDI2_DCORE3_ENGINE_ID_TPC_3,
+ GAUDI2_DCORE3_ENGINE_ID_TPC_4,
+ GAUDI2_DCORE3_ENGINE_ID_TPC_5,
+ GAUDI2_DCORE3_ENGINE_ID_DEC_0,
+ GAUDI2_DCORE3_ENGINE_ID_DEC_1,
+ GAUDI2_DCORE0_ENGINE_ID_TPC_6,
+ GAUDI2_ENGINE_ID_PDMA_0,
+ GAUDI2_ENGINE_ID_PDMA_1,
+ GAUDI2_ENGINE_ID_ROT_0,
+ GAUDI2_ENGINE_ID_ROT_1,
+ GAUDI2_PCIE_ENGINE_ID_DEC_0,
+ GAUDI2_PCIE_ENGINE_ID_DEC_1,
+ GAUDI2_ENGINE_ID_NIC0_0,
+ GAUDI2_ENGINE_ID_NIC0_1,
+ GAUDI2_ENGINE_ID_NIC1_0,
+ GAUDI2_ENGINE_ID_NIC1_1,
+ GAUDI2_ENGINE_ID_NIC2_0,
+ GAUDI2_ENGINE_ID_NIC2_1,
+ GAUDI2_ENGINE_ID_NIC3_0,
+ GAUDI2_ENGINE_ID_NIC3_1,
+ GAUDI2_ENGINE_ID_NIC4_0,
+ GAUDI2_ENGINE_ID_NIC4_1,
+ GAUDI2_ENGINE_ID_NIC5_0,
+ GAUDI2_ENGINE_ID_NIC5_1,
+ GAUDI2_ENGINE_ID_NIC6_0,
+ GAUDI2_ENGINE_ID_NIC6_1,
+ GAUDI2_ENGINE_ID_NIC7_0,
+ GAUDI2_ENGINE_ID_NIC7_1,
+ GAUDI2_ENGINE_ID_NIC8_0,
+ GAUDI2_ENGINE_ID_NIC8_1,
+ GAUDI2_ENGINE_ID_NIC9_0,
+ GAUDI2_ENGINE_ID_NIC9_1,
+ GAUDI2_ENGINE_ID_NIC10_0,
+ GAUDI2_ENGINE_ID_NIC10_1,
+ GAUDI2_ENGINE_ID_NIC11_0,
+ GAUDI2_ENGINE_ID_NIC11_1,
+ GAUDI2_ENGINE_ID_SIZE
+};
enum hl_goya_pll_index {
HL_GOYA_CPU_PLL = 0,
HL_GOYA_IC_PLL,
@@ -231,20 +574,48 @@
HL_GAUDI_IF_PLL,
HL_GAUDI_PLL_MAX
};
+enum hl_gaudi2_pll_index {
+ HL_GAUDI2_CPU_PLL = 0,
+ HL_GAUDI2_PCI_PLL,
+ HL_GAUDI2_SRAM_PLL,
+ HL_GAUDI2_HBM_PLL,
+ HL_GAUDI2_NIC_PLL,
+ HL_GAUDI2_DMA_PLL,
+ HL_GAUDI2_MESH_PLL,
+ HL_GAUDI2_MME_PLL,
+ HL_GAUDI2_TPC_PLL,
+ HL_GAUDI2_IF_PLL,
+ HL_GAUDI2_VID_PLL,
+ HL_GAUDI2_MSS_PLL,
+ HL_GAUDI2_PLL_MAX
+};
+enum hl_goya_dma_direction {
+ HL_DMA_HOST_TO_DRAM,
+ HL_DMA_HOST_TO_SRAM,
+ HL_DMA_DRAM_TO_SRAM,
+ HL_DMA_SRAM_TO_DRAM,
+ HL_DMA_SRAM_TO_HOST,
+ HL_DMA_DRAM_TO_HOST,
+ HL_DMA_DRAM_TO_DRAM,
+ HL_DMA_SRAM_TO_SRAM,
+ HL_DMA_ENUM_MAX
+};
enum hl_device_status {
HL_DEVICE_STATUS_OPERATIONAL,
HL_DEVICE_STATUS_IN_RESET,
HL_DEVICE_STATUS_MALFUNCTION,
HL_DEVICE_STATUS_NEEDS_RESET,
HL_DEVICE_STATUS_IN_DEVICE_CREATION,
- HL_DEVICE_STATUS_LAST = HL_DEVICE_STATUS_IN_DEVICE_CREATION
+ HL_DEVICE_STATUS_IN_RESET_AFTER_DEVICE_RELEASE,
+ HL_DEVICE_STATUS_LAST = HL_DEVICE_STATUS_IN_RESET_AFTER_DEVICE_RELEASE
};
enum hl_server_type {
HL_SERVER_TYPE_UNKNOWN = 0,
HL_SERVER_GAUDI_HLS1 = 1,
HL_SERVER_GAUDI_HLS1H = 2,
HL_SERVER_GAUDI_TYPE1 = 3,
- HL_SERVER_GAUDI_TYPE2 = 4
+ HL_SERVER_GAUDI_TYPE2 = 4,
+ HL_SERVER_GAUDI2_HLS2 = 5
};
#define HL_INFO_HW_IP_INFO 0
#define HL_INFO_HW_EVENTS 1
@@ -269,6 +640,11 @@
#define HL_INFO_LAST_ERR_OPEN_DEV_TIME 23
#define HL_INFO_CS_TIMEOUT_EVENT 24
#define HL_INFO_RAZWI_EVENT 25
+#define HL_INFO_DEV_MEM_ALLOC_PAGE_SIZES 26
+#define HL_INFO_REGISTER_EVENTFD 28
+#define HL_INFO_UNREGISTER_EVENTFD 29
+#define HL_INFO_GET_EVENTS 30
+#define HL_INFO_UNDEFINED_OPCODE_EVENT 31
#define HL_INFO_VERSION_MAX_LEN 128
#define HL_INFO_CARD_NAME_MAX_LEN 16
struct hl_info_hw_ip_info {
@@ -279,7 +655,7 @@
__u32 num_of_events;
__u32 device_id;
__u32 module_id;
- __u32 reserved;
+ __u32 decoder_enabled_mask;
__u16 first_available_interrupt_id;
__u16 server_type;
__u32 cpld_version;
@@ -289,11 +665,17 @@
__u32 psoc_pci_pll_div_factor;
__u8 tpc_enabled_mask;
__u8 dram_enabled;
- __u8 pad[2];
+ __u8 reserved;
+ __u8 mme_master_slave_mode;
__u8 cpucp_version[HL_INFO_VERSION_MAX_LEN];
__u8 card_name[HL_INFO_CARD_NAME_MAX_LEN];
- __u64 reserved2;
+ __u64 tpc_enabled_mask_ext;
__u64 dram_page_size;
+ __u32 edma_enabled_mask;
+ __u16 number_of_user_interrupts;
+ __u16 pad2;
+ __u64 reserved4;
+ __u64 device_mem_alloc_default_page_size;
};
struct hl_info_dram_usage {
__u64 dram_free_mem;
@@ -353,6 +735,9 @@
struct hl_open_stats_info {
__u64 open_counter;
__u64 last_open_period_ms;
+ __u8 is_compute_ctx_active;
+ __u8 compute_ctx_in_release;
+ __u8 pad[6];
};
struct hl_power_info {
__u64 power;
@@ -395,6 +780,20 @@
__u8 error_type;
__u8 pad[2];
};
+#define MAX_QMAN_STREAMS_INFO 4
+#define OPCODE_INFO_MAX_ADDR_SIZE 8
+struct hl_info_undefined_opcode_event {
+ __s64 timestamp;
+ __u64 cb_addr_streams[MAX_QMAN_STREAMS_INFO][OPCODE_INFO_MAX_ADDR_SIZE];
+ __u64 cq_addr;
+ __u32 cq_size;
+ __u32 cb_addr_streams_len;
+ __u32 engine_id;
+ __u32 stream_id;
+};
+struct hl_info_dev_memalloc_page_sizes {
+ __u64 page_order_bitmask;
+};
enum gaudi_dcores {
HL_GAUDI_WS_DCORE,
HL_GAUDI_WN_DCORE,
@@ -410,6 +809,7 @@
__u32 ctx_id;
__u32 period_ms;
__u32 pll_index;
+ __u32 eventfd;
};
__u32 pad;
};
@@ -490,6 +890,7 @@
__u32 timeout;
__u32 cs_flags;
__u32 ctx_id;
+ __u8 pad[4];
};
struct hl_cs_out {
union {
@@ -510,8 +911,11 @@
};
#define HL_WAIT_CS_FLAGS_INTERRUPT 0x2
#define HL_WAIT_CS_FLAGS_INTERRUPT_MASK 0xFFF00000
+#define HL_WAIT_CS_FLAGS_ANY_CQ_INTERRUPT 0xFFF00000
+#define HL_WAIT_CS_FLAGS_ANY_DEC_INTERRUPT 0xFFE00000
#define HL_WAIT_CS_FLAGS_MULTI_CS 0x4
#define HL_WAIT_CS_FLAGS_INTERRUPT_KERNEL_CQ 0x10
+#define HL_WAIT_CS_FLAGS_REGISTER_INTERRUPT 0x20
#define HL_WAIT_MULTI_CS_LIST_MAX_LEN 32
struct hl_wait_cs_in {
union {
@@ -537,6 +941,8 @@
__u64 interrupt_timeout_us;
};
__u64 cq_counters_offset;
+ __u64 timestamp_handle;
+ __u64 timestamp_offset;
};
#define HL_WAIT_CS_STATUS_COMPLETED 0
#define HL_WAIT_CS_STATUS_BUSY 1
@@ -561,14 +967,17 @@
#define HL_MEM_OP_UNMAP 3
#define HL_MEM_OP_MAP_BLOCK 4
#define HL_MEM_OP_EXPORT_DMABUF_FD 5
+#define HL_MEM_OP_TS_ALLOC 6
#define HL_MEM_CONTIGUOUS 0x1
#define HL_MEM_SHARED 0x2
#define HL_MEM_USERPTR 0x4
#define HL_MEM_FORCE_HINT 0x8
+#define HL_MEM_PREFETCH 0x40
struct hl_mem_in {
union {
struct {
__u64 mem_size;
+ __u64 page_size;
} alloc;
struct {
__u64 handle;
@@ -596,7 +1005,7 @@
__u32 op;
__u32 flags;
__u32 ctx_id;
- __u32 pad;
+ __u32 num_of_elements;
};
struct hl_mem_out {
union {
@@ -641,12 +1050,18 @@
__u32 bw_win;
__u32 win_capture;
__u32 id;
- __u32 pad;
+ __u32 control;
+ __u64 start_addr2;
+ __u64 end_addr2;
+ __u64 start_addr3;
+ __u64 end_addr3;
};
struct hl_debug_params_spmu {
__u64 event_types[HL_DEBUG_MAX_AUX_VALUES];
__u32 event_types_num;
- __u32 pad;
+ __u32 pmtrc_val;
+ __u32 trc_ctrl_host_val;
+ __u32 trc_en_host_val;
};
#define HL_DEBUG_OP_ETR 0
#define HL_DEBUG_OP_ETF 1
@@ -666,6 +1081,11 @@
__u32 enable;
__u32 ctx_id;
};
+#define HL_NOTIFIER_EVENT_TPC_ASSERT (1ULL << 0)
+#define HL_NOTIFIER_EVENT_UNDEFINED_OPCODE (1ULL << 1)
+#define HL_NOTIFIER_EVENT_DEVICE_RESET (1ULL << 2)
+#define HL_NOTIFIER_EVENT_CS_TIMEOUT (1ULL << 3)
+#define HL_NOTIFIER_EVENT_DEVICE_UNAVAILABLE (1ULL << 4)
#define HL_IOCTL_INFO _IOWR('H', 0x01, struct hl_info_args)
#define HL_IOCTL_CB _IOWR('H', 0x02, union hl_cb_args)
#define HL_IOCTL_CS _IOWR('H', 0x03, union hl_cs_args)
diff --git a/libc/kernel/uapi/rdma/erdma-abi.h b/libc/kernel/uapi/rdma/erdma-abi.h
new file mode 100644
index 0000000..4df1757
--- /dev/null
+++ b/libc/kernel/uapi/rdma/erdma-abi.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 __ERDMA_USER_H__
+#define __ERDMA_USER_H__
+#include <linux/types.h>
+#define ERDMA_ABI_VERSION 1
+struct erdma_ureq_create_cq {
+ __aligned_u64 db_record_va;
+ __aligned_u64 qbuf_va;
+ __u32 qbuf_len;
+ __u32 rsvd0;
+};
+struct erdma_uresp_create_cq {
+ __u32 cq_id;
+ __u32 num_cqe;
+};
+struct erdma_ureq_create_qp {
+ __aligned_u64 db_record_va;
+ __aligned_u64 qbuf_va;
+ __u32 qbuf_len;
+ __u32 rsvd0;
+};
+struct erdma_uresp_create_qp {
+ __u32 qp_id;
+ __u32 num_sqe;
+ __u32 num_rqe;
+ __u32 rq_offset;
+};
+struct erdma_uresp_alloc_ctx {
+ __u32 dev_id;
+ __u32 pad;
+ __u32 sdb_type;
+ __u32 sdb_offset;
+ __aligned_u64 sdb;
+ __aligned_u64 rdb;
+ __aligned_u64 cdb;
+};
+#endif
diff --git a/libc/kernel/uapi/rdma/hfi/hfi1_user.h b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
index 3352907..6d58600 100644
--- a/libc/kernel/uapi/rdma/hfi/hfi1_user.h
+++ b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
@@ -80,7 +80,7 @@
struct hfi1_status {
__aligned_u64 dev;
__aligned_u64 port;
- char freezemsg[0];
+ char freezemsg[];
};
enum sdma_req_opcode {
EXPECTED = 0,
diff --git a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
index 3b94907..766d5be 100644
--- a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
@@ -191,6 +191,7 @@
RDMA_DRIVER_QIB,
RDMA_DRIVER_EFA,
RDMA_DRIVER_SIW,
+ RDMA_DRIVER_ERDMA,
};
enum ib_uverbs_gid_type {
IB_UVERBS_GID_TYPE_IB,
diff --git a/libc/kernel/uapi/rdma/ib_user_verbs.h b/libc/kernel/uapi/rdma/ib_user_verbs.h
index d9ac9e0..552c80a 100644
--- a/libc/kernel/uapi/rdma/ib_user_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_verbs.h
@@ -106,16 +106,16 @@
};
struct ib_uverbs_get_context {
__aligned_u64 response;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_get_context_resp {
__u32 async_fd;
__u32 num_comp_vectors;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_query_device {
__aligned_u64 response;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_query_device_resp {
__aligned_u64 fw_ver;
@@ -208,7 +208,7 @@
__aligned_u64 response;
__u8 port_num;
__u8 reserved[7];
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_query_port_resp {
__u32 port_cap_flags;
@@ -236,11 +236,11 @@
};
struct ib_uverbs_alloc_pd {
__aligned_u64 response;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_alloc_pd_resp {
__u32 pd_handle;
- __u32 driver_data[0];
+ __u32 driver_data[];
};
struct ib_uverbs_dealloc_pd {
__u32 pd_handle;
@@ -249,11 +249,11 @@
__aligned_u64 response;
__u32 fd;
__u32 oflags;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_open_xrcd_resp {
__u32 xrcd_handle;
- __u32 driver_data[0];
+ __u32 driver_data[];
};
struct ib_uverbs_close_xrcd {
__u32 xrcd_handle;
@@ -265,13 +265,13 @@
__aligned_u64 hca_va;
__u32 pd_handle;
__u32 access_flags;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_reg_mr_resp {
__u32 mr_handle;
__u32 lkey;
__u32 rkey;
- __u32 driver_data[0];
+ __u32 driver_data[];
};
struct ib_uverbs_rereg_mr {
__aligned_u64 response;
@@ -282,12 +282,12 @@
__aligned_u64 hca_va;
__u32 pd_handle;
__u32 access_flags;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_rereg_mr_resp {
__u32 lkey;
__u32 rkey;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_dereg_mr {
__u32 mr_handle;
@@ -297,12 +297,12 @@
__u32 pd_handle;
__u8 mw_type;
__u8 reserved[3];
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_alloc_mw_resp {
__u32 mw_handle;
__u32 rkey;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_dealloc_mw {
__u32 mw_handle;
@@ -320,7 +320,7 @@
__u32 comp_vector;
__s32 comp_channel;
__u32 reserved;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
enum ib_uverbs_ex_create_cq_flags {
IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION = 1 << 0,
@@ -349,12 +349,12 @@
__aligned_u64 response;
__u32 cq_handle;
__u32 cqe;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_resize_cq_resp {
__u32 cqe;
__u32 reserved;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_poll_cq {
__aligned_u64 response;
@@ -394,7 +394,7 @@
struct ib_uverbs_poll_cq_resp {
__u32 count;
__u32 reserved;
- struct ib_uverbs_wc wc[0];
+ struct ib_uverbs_wc wc[];
};
struct ib_uverbs_req_notify_cq {
__u32 cq_handle;
@@ -476,7 +476,7 @@
__u8 qp_type;
__u8 is_srq;
__u8 reserved;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
enum ib_uverbs_create_qp_mask {
IB_UVERBS_CREATE_QP_MASK_IND_TABLE = 1UL << 0,
@@ -511,7 +511,7 @@
__u32 qpn;
__u8 qp_type;
__u8 reserved[7];
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_create_qp_resp {
__u32 qp_handle;
@@ -547,7 +547,7 @@
__aligned_u64 response;
__u32 qp_handle;
__u32 attr_mask;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_query_qp_resp {
struct ib_uverbs_qp_dest dest;
@@ -580,7 +580,7 @@
__u8 alt_timeout;
__u8 sq_sig_all;
__u8 reserved[5];
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_modify_qp {
struct ib_uverbs_qp_dest dest;
@@ -685,7 +685,7 @@
__u32 wr_count;
__u32 sge_count;
__u32 wqe_size;
- struct ib_uverbs_send_wr send_wr[0];
+ struct ib_uverbs_send_wr send_wr[];
};
struct ib_uverbs_post_send_resp {
__u32 bad_wr;
@@ -701,7 +701,7 @@
__u32 wr_count;
__u32 sge_count;
__u32 wqe_size;
- struct ib_uverbs_recv_wr recv_wr[0];
+ struct ib_uverbs_recv_wr recv_wr[];
};
struct ib_uverbs_post_recv_resp {
__u32 bad_wr;
@@ -712,7 +712,7 @@
__u32 wr_count;
__u32 sge_count;
__u32 wqe_size;
- struct ib_uverbs_recv_wr recv[0];
+ struct ib_uverbs_recv_wr recv[];
};
struct ib_uverbs_post_srq_recv_resp {
__u32 bad_wr;
@@ -723,11 +723,11 @@
__u32 pd_handle;
__u32 reserved;
struct ib_uverbs_ah_attr attr;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_create_ah_resp {
__u32 ah_handle;
- __u32 driver_data[0];
+ __u32 driver_data[];
};
struct ib_uverbs_destroy_ah {
__u32 ah_handle;
@@ -737,14 +737,14 @@
__u32 qp_handle;
__u16 mlid;
__u16 reserved;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_detach_mcast {
__u8 gid[16];
__u32 qp_handle;
__u16 mlid;
__u16 reserved;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_flow_spec_hdr {
__u32 type;
@@ -944,7 +944,7 @@
__u8 reserved[2];
__u8 port;
__u32 flags;
- struct ib_uverbs_flow_spec_hdr flow_specs[0];
+ struct ib_uverbs_flow_spec_hdr flow_specs[];
};
struct ib_uverbs_create_flow {
__u32 comp_mask;
@@ -966,7 +966,7 @@
__u32 max_wr;
__u32 max_sge;
__u32 srq_limit;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_create_xsrq {
__aligned_u64 response;
@@ -979,27 +979,27 @@
__u32 max_num_tags;
__u32 xrcd_handle;
__u32 cq_handle;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_create_srq_resp {
__u32 srq_handle;
__u32 max_wr;
__u32 max_sge;
__u32 srqn;
- __u32 driver_data[0];
+ __u32 driver_data[];
};
struct ib_uverbs_modify_srq {
__u32 srq_handle;
__u32 attr_mask;
__u32 max_wr;
__u32 srq_limit;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_query_srq {
__aligned_u64 response;
__u32 srq_handle;
__u32 reserved;
- __aligned_u64 driver_data[0];
+ __aligned_u64 driver_data[];
};
struct ib_uverbs_query_srq_resp {
__u32 max_wr;
@@ -1056,7 +1056,7 @@
struct ib_uverbs_ex_create_rwq_ind_table {
__u32 comp_mask;
__u32 log_ind_tbl_size;
- __u32 wq_handles[0];
+ __u32 wq_handles[];
};
struct ib_uverbs_ex_create_rwq_ind_table_resp {
__u32 comp_mask;
@@ -1079,4 +1079,37 @@
__u32 reserved;
};
#define IB_DEVICE_NAME_MAX 64
+enum ib_uverbs_device_cap_flags {
+ IB_UVERBS_DEVICE_RESIZE_MAX_WR = 1 << 0,
+ IB_UVERBS_DEVICE_BAD_PKEY_CNTR = 1 << 1,
+ IB_UVERBS_DEVICE_BAD_QKEY_CNTR = 1 << 2,
+ IB_UVERBS_DEVICE_RAW_MULTI = 1 << 3,
+ IB_UVERBS_DEVICE_AUTO_PATH_MIG = 1 << 4,
+ IB_UVERBS_DEVICE_CHANGE_PHY_PORT = 1 << 5,
+ IB_UVERBS_DEVICE_UD_AV_PORT_ENFORCE = 1 << 6,
+ IB_UVERBS_DEVICE_CURR_QP_STATE_MOD = 1 << 7,
+ IB_UVERBS_DEVICE_SHUTDOWN_PORT = 1 << 8,
+ IB_UVERBS_DEVICE_PORT_ACTIVE_EVENT = 1 << 10,
+ IB_UVERBS_DEVICE_SYS_IMAGE_GUID = 1 << 11,
+ IB_UVERBS_DEVICE_RC_RNR_NAK_GEN = 1 << 12,
+ IB_UVERBS_DEVICE_SRQ_RESIZE = 1 << 13,
+ IB_UVERBS_DEVICE_N_NOTIFY_CQ = 1 << 14,
+ IB_UVERBS_DEVICE_MEM_WINDOW = 1 << 17,
+ IB_UVERBS_DEVICE_UD_IP_CSUM = 1 << 18,
+ IB_UVERBS_DEVICE_XRC = 1 << 20,
+ IB_UVERBS_DEVICE_MEM_MGT_EXTENSIONS = 1 << 21,
+ IB_UVERBS_DEVICE_MEM_WINDOW_TYPE_2A = 1 << 23,
+ IB_UVERBS_DEVICE_MEM_WINDOW_TYPE_2B = 1 << 24,
+ IB_UVERBS_DEVICE_RC_IP_CSUM = 1 << 25,
+ IB_UVERBS_DEVICE_RAW_IP_CSUM = 1 << 26,
+ IB_UVERBS_DEVICE_MANAGED_FLOW_STEERING = 1 << 29,
+ IB_UVERBS_DEVICE_RAW_SCATTER_FCS = 1ULL << 34,
+ IB_UVERBS_DEVICE_PCI_WRITE_END_PADDING = 1ULL << 36,
+};
+enum ib_uverbs_raw_packet_caps {
+ IB_UVERBS_RAW_PACKET_CAP_CVLAN_STRIPPING = 1 << 0,
+ IB_UVERBS_RAW_PACKET_CAP_SCATTER_FCS = 1 << 1,
+ IB_UVERBS_RAW_PACKET_CAP_IP_CSUM = 1 << 2,
+ IB_UVERBS_RAW_PACKET_CAP_DELAY_DROP = 1 << 3,
+};
#endif
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
index 862abcb..dc3eb1f 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -179,6 +179,7 @@
MLX5_IB_OBJECT_VAR,
MLX5_IB_OBJECT_PP,
MLX5_IB_OBJECT_UAR,
+ MLX5_IB_OBJECT_STEERING_ANCHOR,
};
enum mlx5_ib_flow_matcher_create_attrs {
MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
@@ -195,6 +196,19 @@
MLX5_IB_METHOD_FLOW_MATCHER_CREATE = (1U << UVERBS_ID_NS_SHIFT),
MLX5_IB_METHOD_FLOW_MATCHER_DESTROY,
};
+enum mlx5_ib_flow_steering_anchor_create_attrs {
+ MLX5_IB_ATTR_STEERING_ANCHOR_CREATE_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+ MLX5_IB_ATTR_STEERING_ANCHOR_FT_TYPE,
+ MLX5_IB_ATTR_STEERING_ANCHOR_PRIORITY,
+ MLX5_IB_ATTR_STEERING_ANCHOR_FT_ID,
+};
+enum mlx5_ib_flow_steering_anchor_destroy_attrs {
+ MLX5_IB_ATTR_STEERING_ANCHOR_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+};
+enum mlx5_ib_steering_anchor_methods {
+ MLX5_IB_METHOD_STEERING_ANCHOR_CREATE = (1U << UVERBS_ID_NS_SHIFT),
+ MLX5_IB_METHOD_STEERING_ANCHOR_DESTROY,
+};
enum mlx5_ib_device_query_context_attrs {
MLX5_IB_ATTR_QUERY_CONTEXT_RESP_UCTX = (1U << UVERBS_ID_NS_SHIFT),
};
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
index c3c3f89..f68c0b3 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
@@ -43,6 +43,7 @@
MLX5_IB_UAPI_DM_TYPE_MEMIC,
MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM,
MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM,
+ MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM,
};
enum mlx5_ib_uapi_devx_create_event_channel_flags {
MLX5_IB_UAPI_DEVX_CR_EV_CH_FLAGS_OMIT_DATA = 1 << 0,
diff --git a/libc/kernel/uapi/rdma/rdma_user_cm.h b/libc/kernel/uapi/rdma/rdma_user_cm.h
index 7b1f7ee..37927f8 100644
--- a/libc/kernel/uapi/rdma/rdma_user_cm.h
+++ b/libc/kernel/uapi/rdma/rdma_user_cm.h
@@ -145,7 +145,7 @@
struct rdma_ucm_query_path_resp {
__u32 num_paths;
__u32 reserved;
- struct ib_path_rec_data path_data[0];
+ struct ib_path_rec_data path_data[];
};
struct rdma_ucm_conn_param {
__u32 qp_num;
diff --git a/libc/kernel/uapi/rdma/rdma_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/rdma_user_ioctl_cmds.h
index 22adfaa..dbaf9ed 100644
--- a/libc/kernel/uapi/rdma/rdma_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/rdma_user_ioctl_cmds.h
@@ -50,6 +50,6 @@
__aligned_u64 reserved1;
__u32 driver_id;
__u32 reserved2;
- struct ib_uverbs_attr attrs[0];
+ struct ib_uverbs_attr attrs[];
};
#endif
diff --git a/libc/kernel/uapi/scsi/fc/fc_els.h b/libc/kernel/uapi/scsi/fc/fc_els.h
index 04ae5b8..d29287d 100644
--- a/libc/kernel/uapi/scsi/fc/fc_els.h
+++ b/libc/kernel/uapi/scsi/fc/fc_els.h
@@ -142,7 +142,7 @@
struct fc_tlv_desc {
__be32 desc_tag;
__be32 desc_len;
- __u8 desc_value[0];
+ __u8 desc_value[];
};
#define FC_TLV_DESC_HDR_SZ sizeof(struct fc_tlv_desc)
#define FC_TLV_DESC_LENGTH_FROM_SZ(desc) (sizeof(desc) - FC_TLV_DESC_HDR_SZ)
@@ -618,7 +618,7 @@
__be32 event_threshold;
__be32 event_count;
__be32 pname_count;
- __be64 pname_list[0];
+ __be64 pname_list[];
};
struct fc_fn_deli_desc {
__be32 desc_tag;
@@ -636,7 +636,7 @@
__be16 event_modifier;
__be32 event_period;
__be32 pname_count;
- __be64 pname_list[0];
+ __be64 pname_list[];
};
struct fc_fn_congn_desc {
__be32 desc_tag;
@@ -651,25 +651,25 @@
__u8 fpin_cmd;
__u8 fpin_zero[3];
__be32 desc_len;
- struct fc_tlv_desc fpin_desc[0];
+ struct fc_tlv_desc fpin_desc[];
};
struct fc_df_desc_fpin_reg {
__be32 desc_tag;
__be32 desc_len;
__be32 count;
- __be32 desc_tags[0];
+ __be32 desc_tags[];
};
struct fc_els_rdf {
__u8 fpin_cmd;
__u8 fpin_zero[3];
__be32 desc_len;
- struct fc_tlv_desc desc[0];
+ struct fc_tlv_desc desc[];
};
struct fc_els_rdf_resp {
struct fc_els_ls_acc acc_hdr;
__be32 desc_list_len;
struct fc_els_lsri_desc lsri;
- struct fc_tlv_desc desc[0];
+ struct fc_tlv_desc desc[];
};
struct fc_diag_lnkflt_desc {
__be32 desc_tag;
@@ -707,12 +707,12 @@
__u8 edc_cmd;
__u8 edc_zero[3];
__be32 desc_len;
- struct fc_tlv_desc desc[0];
+ struct fc_tlv_desc desc[];
};
struct fc_els_edc_resp {
struct fc_els_ls_acc acc_hdr;
__be32 desc_list_len;
struct fc_els_lsri_desc lsri;
- struct fc_tlv_desc desc[0];
+ struct fc_tlv_desc desc[];
};
#endif
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_fc.h b/libc/kernel/uapi/scsi/scsi_bsg_fc.h
index 8966f61..2647249 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_fc.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_fc.h
@@ -66,7 +66,7 @@
};
struct fc_bsg_host_vendor {
__u64 vendor_id;
- __u32 vendor_cmd[0];
+ __u32 vendor_cmd[];
};
struct fc_bsg_host_vendor_reply {
__u32 vendor_rsp[0];
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
new file mode 100644
index 0000000..fcba8cd
--- /dev/null
+++ b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
@@ -0,0 +1,333 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** 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 SCSI_BSG_MPI3MR_H_INCLUDED
+#define SCSI_BSG_MPI3MR_H_INCLUDED
+#include <linux/types.h>
+#define MPI3MR_IOCTL_VERSION 0x06
+#define MPI3MR_APP_DEFAULT_TIMEOUT (60)
+#define MPI3MR_BSG_ADPTYPE_UNKNOWN 0
+#define MPI3MR_BSG_ADPTYPE_AVGFAMILY 1
+#define MPI3MR_BSG_ADPSTATE_UNKNOWN 0
+#define MPI3MR_BSG_ADPSTATE_OPERATIONAL 1
+#define MPI3MR_BSG_ADPSTATE_FAULT 2
+#define MPI3MR_BSG_ADPSTATE_IN_RESET 3
+#define MPI3MR_BSG_ADPSTATE_UNRECOVERABLE 4
+#define MPI3MR_BSG_ADPRESET_UNKNOWN 0
+#define MPI3MR_BSG_ADPRESET_SOFT 1
+#define MPI3MR_BSG_ADPRESET_DIAG_FAULT 2
+#define MPI3MR_BSG_LOGDATA_MAX_ENTRIES 400
+#define MPI3MR_BSG_LOGDATA_ENTRY_HEADER_SZ 4
+#define MPI3MR_DRVBSG_OPCODE_UNKNOWN 0
+#define MPI3MR_DRVBSG_OPCODE_ADPINFO 1
+#define MPI3MR_DRVBSG_OPCODE_ADPRESET 2
+#define MPI3MR_DRVBSG_OPCODE_ALLTGTDEVINFO 4
+#define MPI3MR_DRVBSG_OPCODE_GETCHGCNT 5
+#define MPI3MR_DRVBSG_OPCODE_LOGDATAENABLE 6
+#define MPI3MR_DRVBSG_OPCODE_PELENABLE 7
+#define MPI3MR_DRVBSG_OPCODE_GETLOGDATA 8
+#define MPI3MR_DRVBSG_OPCODE_QUERY_HDB 9
+#define MPI3MR_DRVBSG_OPCODE_REPOST_HDB 10
+#define MPI3MR_DRVBSG_OPCODE_UPLOAD_HDB 11
+#define MPI3MR_DRVBSG_OPCODE_REFRESH_HDB_TRIGGERS 12
+#define MPI3MR_BSG_BUFTYPE_UNKNOWN 0
+#define MPI3MR_BSG_BUFTYPE_RAIDMGMT_CMD 1
+#define MPI3MR_BSG_BUFTYPE_RAIDMGMT_RESP 2
+#define MPI3MR_BSG_BUFTYPE_DATA_IN 3
+#define MPI3MR_BSG_BUFTYPE_DATA_OUT 4
+#define MPI3MR_BSG_BUFTYPE_MPI_REPLY 5
+#define MPI3MR_BSG_BUFTYPE_ERR_RESPONSE 6
+#define MPI3MR_BSG_BUFTYPE_MPI_REQUEST 0xFE
+#define MPI3MR_BSG_MPI_REPLY_BUFTYPE_UNKNOWN 0
+#define MPI3MR_BSG_MPI_REPLY_BUFTYPE_STATUS 1
+#define MPI3MR_BSG_MPI_REPLY_BUFTYPE_ADDRESS 2
+#define MPI3MR_HDB_BUFTYPE_UNKNOWN 0
+#define MPI3MR_HDB_BUFTYPE_TRACE 1
+#define MPI3MR_HDB_BUFTYPE_FIRMWARE 2
+#define MPI3MR_HDB_BUFTYPE_RESERVED 3
+#define MPI3MR_HDB_BUFSTATUS_UNKNOWN 0
+#define MPI3MR_HDB_BUFSTATUS_NOT_ALLOCATED 1
+#define MPI3MR_HDB_BUFSTATUS_POSTED_UNPAUSED 2
+#define MPI3MR_HDB_BUFSTATUS_POSTED_PAUSED 3
+#define MPI3MR_HDB_BUFSTATUS_RELEASED 4
+#define MPI3MR_HDB_TRIGGER_TYPE_UNKNOWN 0
+#define MPI3MR_HDB_TRIGGER_TYPE_DIAGFAULT 1
+#define MPI3MR_HDB_TRIGGER_TYPE_ELEMENT 2
+#define MPI3MR_HDB_TRIGGER_TYPE_MASTER 3
+enum command {
+ MPI3MR_DRV_CMD = 1,
+ MPI3MR_MPT_CMD = 2,
+};
+struct mpi3_driver_info_layout {
+ __le32 information_length;
+ __u8 driver_signature[12];
+ __u8 os_name[16];
+ __u8 os_version[12];
+ __u8 driver_name[20];
+ __u8 driver_version[32];
+ __u8 driver_release_date[20];
+ __le32 driver_capabilities;
+};
+struct mpi3mr_bsg_in_adpinfo {
+ __u32 adp_type;
+ __u32 rsvd1;
+ __u32 pci_dev_id;
+ __u32 pci_dev_hw_rev;
+ __u32 pci_subsys_dev_id;
+ __u32 pci_subsys_ven_id;
+ __u32 pci_dev : 5;
+ __u32 pci_func : 3;
+ __u32 pci_bus : 8;
+ __u16 rsvd2;
+ __u32 pci_seg_id;
+ __u32 app_intfc_ver;
+ __u8 adp_state;
+ __u8 rsvd3;
+ __u16 rsvd4;
+ __u32 rsvd5[2];
+ struct mpi3_driver_info_layout driver_info;
+};
+struct mpi3mr_bsg_adp_reset {
+ __u8 reset_type;
+ __u8 rsvd1;
+ __u16 rsvd2;
+};
+struct mpi3mr_change_count {
+ __u16 change_count;
+ __u16 rsvd;
+};
+struct mpi3mr_device_map_info {
+ __u16 handle;
+ __u16 perst_id;
+ __u32 target_id;
+ __u8 bus_id;
+ __u8 rsvd1;
+ __u16 rsvd2;
+};
+struct mpi3mr_all_tgt_info {
+ __u16 num_devices;
+ __u16 rsvd1;
+ __u32 rsvd2;
+ struct mpi3mr_device_map_info dmi[1];
+};
+struct mpi3mr_logdata_enable {
+ __u16 max_entries;
+ __u16 rsvd;
+};
+struct mpi3mr_bsg_out_pel_enable {
+ __u16 pel_locale;
+ __u8 pel_class;
+ __u8 rsvd;
+};
+struct mpi3mr_logdata_entry {
+ __u8 valid_entry;
+ __u8 rsvd1;
+ __u16 rsvd2;
+ __u8 data[1];
+};
+struct mpi3mr_bsg_in_log_data {
+ struct mpi3mr_logdata_entry entry[1];
+};
+struct mpi3mr_hdb_entry {
+ __u8 buf_type;
+ __u8 status;
+ __u8 trigger_type;
+ __u8 rsvd1;
+ __u16 size;
+ __u16 rsvd2;
+ __u64 trigger_data;
+ __u32 rsvd3;
+ __u32 rsvd4;
+};
+struct mpi3mr_bsg_in_hdb_status {
+ __u8 num_hdb_types;
+ __u8 rsvd1;
+ __u16 rsvd2;
+ __u32 rsvd3;
+ struct mpi3mr_hdb_entry entry[1];
+};
+struct mpi3mr_bsg_out_repost_hdb {
+ __u8 buf_type;
+ __u8 rsvd1;
+ __u16 rsvd2;
+};
+struct mpi3mr_bsg_out_upload_hdb {
+ __u8 buf_type;
+ __u8 rsvd1;
+ __u16 rsvd2;
+ __u32 start_offset;
+ __u32 length;
+};
+struct mpi3mr_bsg_out_refresh_hdb_triggers {
+ __u8 page_type;
+ __u8 rsvd1;
+ __u16 rsvd2;
+};
+struct mpi3mr_bsg_drv_cmd {
+ __u8 mrioc_id;
+ __u8 opcode;
+ __u16 rsvd1;
+ __u32 rsvd2[4];
+};
+struct mpi3mr_bsg_in_reply_buf {
+ __u8 mpi_reply_type;
+ __u8 rsvd1;
+ __u16 rsvd2;
+ __u8 reply_buf[1];
+};
+struct mpi3mr_buf_entry {
+ __u8 buf_type;
+ __u8 rsvd1;
+ __u16 rsvd2;
+ __u32 buf_len;
+};
+struct mpi3mr_buf_entry_list {
+ __u8 num_of_entries;
+ __u8 rsvd1;
+ __u16 rsvd2;
+ __u32 rsvd3;
+ struct mpi3mr_buf_entry buf_entry[1];
+};
+struct mpi3mr_bsg_mptcmd {
+ __u8 mrioc_id;
+ __u8 rsvd1;
+ __u16 timeout;
+ __u32 rsvd2;
+ struct mpi3mr_buf_entry_list buf_entry_list;
+};
+struct mpi3mr_bsg_packet {
+ __u8 cmd_type;
+ __u8 rsvd1;
+ __u16 rsvd2;
+ __u32 rsvd3;
+ union {
+ struct mpi3mr_bsg_drv_cmd drvrcmd;
+ struct mpi3mr_bsg_mptcmd mptcmd;
+ } cmd;
+};
+#ifndef MPI3_NVME_ENCAP_CMD_MAX
+#define MPI3_NVME_ENCAP_CMD_MAX (1)
+#endif
+struct mpi3_nvme_encapsulated_request {
+ __le16 host_tag;
+ __u8 ioc_use_only02;
+ __u8 function;
+ __le16 ioc_use_only04;
+ __u8 ioc_use_only06;
+ __u8 msg_flags;
+ __le16 change_count;
+ __le16 dev_handle;
+ __le16 encapsulated_command_length;
+ __le16 flags;
+ __le32 data_length;
+ __le32 reserved14[3];
+ __le32 command[MPI3_NVME_ENCAP_CMD_MAX];
+};
+struct mpi3_nvme_encapsulated_error_reply {
+ __le16 host_tag;
+ __u8 ioc_use_only02;
+ __u8 function;
+ __le16 ioc_use_only04;
+ __u8 ioc_use_only06;
+ __u8 msg_flags;
+ __le16 ioc_use_only08;
+ __le16 ioc_status;
+ __le32 ioc_log_info;
+ __le32 nvme_completion_entry[4];
+};
+#define MPI3MR_NVME_PRP_SIZE 8
+#define MPI3MR_NVME_CMD_PRP1_OFFSET 24
+#define MPI3MR_NVME_CMD_PRP2_OFFSET 32
+#define MPI3MR_NVME_CMD_SGL_OFFSET 24
+#define MPI3MR_NVME_DATA_FORMAT_PRP 0
+#define MPI3MR_NVME_DATA_FORMAT_SGL1 1
+#define MPI3MR_NVME_DATA_FORMAT_SGL2 2
+struct mpi3_scsi_task_mgmt_request {
+ __le16 host_tag;
+ __u8 ioc_use_only02;
+ __u8 function;
+ __le16 ioc_use_only04;
+ __u8 ioc_use_only06;
+ __u8 msg_flags;
+ __le16 change_count;
+ __le16 dev_handle;
+ __le16 task_host_tag;
+ __u8 task_type;
+ __u8 reserved0f;
+ __le16 task_request_queue_id;
+ __le16 reserved12;
+ __le32 reserved14;
+ __u8 lun[8];
+};
+#define MPI3_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x08)
+#define MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01)
+#define MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK_SET (0x02)
+#define MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03)
+#define MPI3_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
+#define MPI3_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
+#define MPI3_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
+#define MPI3_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08)
+#define MPI3_SCSITASKMGMT_TASKTYPE_QUERY_TASK_SET (0x09)
+#define MPI3_SCSITASKMGMT_TASKTYPE_QUERY_ASYNC_EVENT (0x0a)
+#define MPI3_SCSITASKMGMT_TASKTYPE_I_T_NEXUS_RESET (0x0b)
+struct mpi3_scsi_task_mgmt_reply {
+ __le16 host_tag;
+ __u8 ioc_use_only02;
+ __u8 function;
+ __le16 ioc_use_only04;
+ __u8 ioc_use_only06;
+ __u8 msg_flags;
+ __le16 ioc_use_only08;
+ __le16 ioc_status;
+ __le32 ioc_log_info;
+ __le32 termination_count;
+ __le32 response_data;
+ __le32 reserved18;
+};
+#define MPI3_SCSITASKMGMT_RSPCODE_TM_COMPLETE (0x00)
+#define MPI3_SCSITASKMGMT_RSPCODE_INVALID_FRAME (0x02)
+#define MPI3_SCSITASKMGMT_RSPCODE_TM_FUNCTION_NOT_SUPPORTED (0x04)
+#define MPI3_SCSITASKMGMT_RSPCODE_TM_FAILED (0x05)
+#define MPI3_SCSITASKMGMT_RSPCODE_TM_SUCCEEDED (0x08)
+#define MPI3_SCSITASKMGMT_RSPCODE_TM_INVALID_LUN (0x09)
+#define MPI3_SCSITASKMGMT_RSPCODE_TM_OVERLAPPED_TAG (0x0a)
+#define MPI3_SCSITASKMGMT_RSPCODE_IO_QUEUED_ON_IOC (0x80)
+#define MPI3_SCSITASKMGMT_RSPCODE_TM_NVME_DENIED (0x81)
+#define MPI3_PEL_LOCALE_FLAGS_NON_BLOCKING_BOOT_EVENT (0x0200)
+#define MPI3_PEL_LOCALE_FLAGS_BLOCKING_BOOT_EVENT (0x0100)
+#define MPI3_PEL_LOCALE_FLAGS_PCIE (0x0080)
+#define MPI3_PEL_LOCALE_FLAGS_CONFIGURATION (0x0040)
+#define MPI3_PEL_LOCALE_FLAGS_CONTROLER (0x0020)
+#define MPI3_PEL_LOCALE_FLAGS_SAS (0x0010)
+#define MPI3_PEL_LOCALE_FLAGS_EPACK (0x0008)
+#define MPI3_PEL_LOCALE_FLAGS_ENCLOSURE (0x0004)
+#define MPI3_PEL_LOCALE_FLAGS_PD (0x0002)
+#define MPI3_PEL_LOCALE_FLAGS_VD (0x0001)
+#define MPI3_PEL_CLASS_DEBUG (0x00)
+#define MPI3_PEL_CLASS_PROGRESS (0x01)
+#define MPI3_PEL_CLASS_INFORMATIONAL (0x02)
+#define MPI3_PEL_CLASS_WARNING (0x03)
+#define MPI3_PEL_CLASS_CRITICAL (0x04)
+#define MPI3_PEL_CLASS_FATAL (0x05)
+#define MPI3_PEL_CLASS_FAULT (0x06)
+#define MPI3_BSG_FUNCTION_MGMT_PASSTHROUGH (0x0a)
+#define MPI3_BSG_FUNCTION_SCSI_IO (0x20)
+#define MPI3_BSG_FUNCTION_SCSI_TASK_MGMT (0x21)
+#define MPI3_BSG_FUNCTION_SMP_PASSTHROUGH (0x22)
+#define MPI3_BSG_FUNCTION_NVME_ENCAPSULATED (0x24)
+#endif
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index b0e47c1..7f496d9 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -884,7 +884,7 @@
struct snd_ctl_tlv {
unsigned int numid;
unsigned int length;
- unsigned int tlv[0];
+ unsigned int tlv[];
};
#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info)
diff --git a/libc/kernel/uapi/sound/firewire.h b/libc/kernel/uapi/sound/firewire.h
index 198a8f4..d26d722 100644
--- a/libc/kernel/uapi/sound/firewire.h
+++ b/libc/kernel/uapi/sound/firewire.h
@@ -46,11 +46,11 @@
__be32 category;
__be32 command;
__be32 status;
- __be32 params[0];
+ __be32 params[];
};
struct snd_firewire_event_efw_response {
unsigned int type;
- __be32 response[0];
+ __be32 response[];
};
struct snd_firewire_event_digi00x_message {
unsigned int type;
@@ -67,7 +67,7 @@
};
struct snd_firewire_event_tascam_control {
unsigned int type;
- struct snd_firewire_tascam_change changes[0];
+ struct snd_firewire_tascam_change changes[];
};
struct snd_firewire_event_motu_register_dsp_change {
unsigned int type;
diff --git a/libc/kernel/uapi/sound/intel/avs/tokens.h b/libc/kernel/uapi/sound/intel/avs/tokens.h
new file mode 100644
index 0000000..b6b3002
--- /dev/null
+++ b/libc/kernel/uapi/sound/intel/avs/tokens.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 __UAPI_SOUND_INTEL_AVS_TOKENS_H
+#define __UAPI_SOUND_INTEL_AVS_TOKENS_H
+enum avs_tplg_token {
+ AVS_TKN_MANIFEST_NAME_STRING = 1,
+ AVS_TKN_MANIFEST_VERSION_U32 = 2,
+ AVS_TKN_MANIFEST_NUM_LIBRARIES_U32 = 3,
+ AVS_TKN_MANIFEST_NUM_AFMTS_U32 = 4,
+ AVS_TKN_MANIFEST_NUM_MODCFGS_BASE_U32 = 5,
+ AVS_TKN_MANIFEST_NUM_MODCFGS_EXT_U32 = 6,
+ AVS_TKN_MANIFEST_NUM_PPLCFGS_U32 = 7,
+ AVS_TKN_MANIFEST_NUM_BINDINGS_U32 = 8,
+ AVS_TKN_LIBRARY_ID_U32 = 101,
+ AVS_TKN_LIBRARY_NAME_STRING = 102,
+ AVS_TKN_AFMT_ID_U32 = 201,
+ AVS_TKN_AFMT_SAMPLE_RATE_U32 = 202,
+ AVS_TKN_AFMT_BIT_DEPTH_U32 = 203,
+ AVS_TKN_AFMT_CHANNEL_MAP_U32 = 204,
+ AVS_TKN_AFMT_CHANNEL_CFG_U32 = 205,
+ AVS_TKN_AFMT_INTERLEAVING_U32 = 206,
+ AVS_TKN_AFMT_NUM_CHANNELS_U32 = 207,
+ AVS_TKN_AFMT_VALID_BIT_DEPTH_U32 = 208,
+ AVS_TKN_AFMT_SAMPLE_TYPE_U32 = 209,
+ AVS_TKN_MODCFG_BASE_ID_U32 = 301,
+ AVS_TKN_MODCFG_BASE_CPC_U32 = 302,
+ AVS_TKN_MODCFG_BASE_IBS_U32 = 303,
+ AVS_TKN_MODCFG_BASE_OBS_U32 = 304,
+ AVS_TKN_MODCFG_BASE_PAGES_U32 = 305,
+ AVS_TKN_MODCFG_EXT_ID_U32 = 401,
+ AVS_TKN_MODCFG_EXT_TYPE_UUID = 402,
+ AVS_TKN_MODCFG_CPR_OUT_AFMT_ID_U32 = 403,
+ AVS_TKN_MODCFG_CPR_FEATURE_MASK_U32 = 404,
+ AVS_TKN_MODCFG_CPR_DMA_TYPE_U32 = 405,
+ AVS_TKN_MODCFG_CPR_DMABUFF_SIZE_U32 = 406,
+ AVS_TKN_MODCFG_CPR_VINDEX_U8 = 407,
+ AVS_TKN_MODCFG_CPR_BLOB_FMT_ID_U32 = 408,
+ AVS_TKN_MODCFG_MICSEL_OUT_AFMT_ID_U32 = 409,
+ AVS_TKN_MODCFG_INTELWOV_CPC_LP_MODE_U32 = 410,
+ AVS_TKN_MODCFG_SRC_OUT_FREQ_U32 = 411,
+ AVS_TKN_MODCFG_MUX_REF_AFMT_ID_U32 = 412,
+ AVS_TKN_MODCFG_MUX_OUT_AFMT_ID_U32 = 413,
+ AVS_TKN_MODCFG_AEC_REF_AFMT_ID_U32 = 414,
+ AVS_TKN_MODCFG_AEC_OUT_AFMT_ID_U32 = 415,
+ AVS_TKN_MODCFG_AEC_CPC_LP_MODE_U32 = 416,
+ AVS_TKN_MODCFG_ASRC_OUT_FREQ_U32 = 417,
+ AVS_TKN_MODCFG_ASRC_MODE_U8 = 418,
+ AVS_TKN_MODCFG_ASRC_DISABLE_JITTER_U8 = 419,
+ AVS_TKN_MODCFG_UPDOWN_MIX_OUT_CHAN_CFG_U32 = 420,
+ AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_SELECT_U32 = 421,
+ AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_0_S32 = 422,
+ AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_1_S32 = 423,
+ AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_2_S32 = 424,
+ AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_3_S32 = 425,
+ AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_4_S32 = 426,
+ AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_5_S32 = 427,
+ AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_6_S32 = 428,
+ AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_7_S32 = 429,
+ AVS_TKN_MODCFG_UPDOWN_MIX_CHAN_MAP_U32 = 430,
+ AVS_TKN_MODCFG_EXT_NUM_INPUT_PINS_U16 = 431,
+ AVS_TKN_MODCFG_EXT_NUM_OUTPUT_PINS_U16 = 432,
+ AVS_TKN_PPLCFG_ID_U32 = 1401,
+ AVS_TKN_PPLCFG_REQ_SIZE_U16 = 1402,
+ AVS_TKN_PPLCFG_PRIORITY_U8 = 1403,
+ AVS_TKN_PPLCFG_LOW_POWER_BOOL = 1404,
+ AVS_TKN_PPLCFG_ATTRIBUTES_U16 = 1405,
+ AVS_TKN_PPLCFG_TRIGGER_U32 = 1406,
+ AVS_TKN_BINDING_ID_U32 = 1501,
+ AVS_TKN_BINDING_TARGET_TPLG_NAME_STRING = 1502,
+ AVS_TKN_BINDING_TARGET_PATH_TMPL_ID_U32 = 1503,
+ AVS_TKN_BINDING_TARGET_PPL_ID_U32 = 1504,
+ AVS_TKN_BINDING_TARGET_MOD_ID_U32 = 1505,
+ AVS_TKN_BINDING_TARGET_MOD_PIN_U8 = 1506,
+ AVS_TKN_BINDING_MOD_ID_U32 = 1507,
+ AVS_TKN_BINDING_MOD_PIN_U8 = 1508,
+ AVS_TKN_BINDING_IS_SINK_U8 = 1509,
+ AVS_TKN_PPL_ID_U32 = 1601,
+ AVS_TKN_PPL_PPLCFG_ID_U32 = 1602,
+ AVS_TKN_PPL_NUM_BINDING_IDS_U32 = 1603,
+ AVS_TKN_PPL_BINDING_ID_U32 = 1604,
+ AVS_TKN_MOD_ID_U32 = 1701,
+ AVS_TKN_MOD_MODCFG_BASE_ID_U32 = 1702,
+ AVS_TKN_MOD_IN_AFMT_ID_U32 = 1703,
+ AVS_TKN_MOD_CORE_ID_U8 = 1704,
+ AVS_TKN_MOD_PROC_DOMAIN_U8 = 1705,
+ AVS_TKN_MOD_MODCFG_EXT_ID_U32 = 1706,
+ AVS_TKN_PATH_TMPL_ID_U32 = 1801,
+ AVS_TKN_PATH_ID_U32 = 1901,
+ AVS_TKN_PATH_FE_FMT_ID_U32 = 1902,
+ AVS_TKN_PATH_BE_FMT_ID_U32 = 1903,
+ AVS_TKN_PIN_FMT_INDEX_U32 = 2201,
+ AVS_TKN_PIN_FMT_IOBS_U32 = 2202,
+ AVS_TKN_PIN_FMT_AFMT_ID_U32 = 2203,
+};
+#endif
diff --git a/libc/kernel/uapi/sound/skl-tplg-interface.h b/libc/kernel/uapi/sound/skl-tplg-interface.h
index b516a08..387d168 100644
--- a/libc/kernel/uapi/sound/skl-tplg-interface.h
+++ b/libc/kernel/uapi/sound/skl-tplg-interface.h
@@ -110,7 +110,7 @@
__u32 rsvd : 30;
__u32 param_id;
__u32 max;
- char params[0];
+ char params[];
} __packed;
enum skl_tkn_dir {
SKL_DIR_IN,
diff --git a/libc/kernel/uapi/sound/sof/abi.h b/libc/kernel/uapi/sound/sof/abi.h
index 3af3c9d..dc4e525 100644
--- a/libc/kernel/uapi/sound/sof/abi.h
+++ b/libc/kernel/uapi/sound/sof/abi.h
@@ -18,8 +18,9 @@
****************************************************************************/
#ifndef __INCLUDE_UAPI_SOUND_SOF_ABI_H__
#define __INCLUDE_UAPI_SOUND_SOF_ABI_H__
+#include <linux/types.h>
#define SOF_ABI_MAJOR 3
-#define SOF_ABI_MINOR 18
+#define SOF_ABI_MINOR 23
#define SOF_ABI_PATCH 0
#define SOF_ABI_MAJOR_SHIFT 24
#define SOF_ABI_MAJOR_MASK 0xff
diff --git a/libc/kernel/uapi/sound/sof/header.h b/libc/kernel/uapi/sound/sof/header.h
index 3fbd4a4..a1a13db 100644
--- a/libc/kernel/uapi/sound/sof/header.h
+++ b/libc/kernel/uapi/sound/sof/header.h
@@ -25,6 +25,19 @@
__u32 size;
__u32 abi;
__u32 reserved[4];
- __u32 data[0];
+ __u32 data[];
} __packed;
+#define SOF_MANIFEST_DATA_TYPE_NHLT 1
+struct sof_manifest_tlv {
+ __le32 type;
+ __le32 size;
+ __u8 data[];
+};
+struct sof_manifest {
+ __le16 abi_major;
+ __le16 abi_minor;
+ __le16 abi_patch;
+ __le16 count;
+ struct sof_manifest_tlv items[];
+};
#endif
diff --git a/libc/kernel/uapi/sound/sof/tokens.h b/libc/kernel/uapi/sound/sof/tokens.h
index 856281a..b07ed42 100644
--- a/libc/kernel/uapi/sound/sof/tokens.h
+++ b/libc/kernel/uapi/sound/sof/tokens.h
@@ -37,8 +37,13 @@
#define SOF_TKN_SCHED_FRAMES 204
#define SOF_TKN_SCHED_TIME_DOMAIN 205
#define SOF_TKN_SCHED_DYNAMIC_PIPELINE 206
+#define SOF_TKN_SCHED_LP_MODE 207
+#define SOF_TKN_SCHED_MEM_USAGE 208
#define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250
#define SOF_TKN_VOLUME_RAMP_STEP_MS 251
+#define SOF_TKN_GAIN_RAMP_TYPE 260
+#define SOF_TKN_GAIN_RAMP_DURATION 261
+#define SOF_TKN_GAIN_VAL 262
#define SOF_TKN_SRC_RATE_IN 300
#define SOF_TKN_SRC_RATE_OUT 301
#define SOF_TKN_ASRC_RATE_IN 320
@@ -51,6 +56,9 @@
#define SOF_TKN_COMP_FORMAT 402
#define SOF_TKN_COMP_CORE_ID 404
#define SOF_TKN_COMP_UUID 405
+#define SOF_TKN_COMP_CPC 406
+#define SOF_TKN_COMP_IS_PAGES 409
+#define SOF_TKN_COMP_NUM_AUDIO_FORMATS 410
#define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500
#define SOF_TKN_INTEL_SSP_MCLK_ID 501
#define SOF_TKN_INTEL_SSP_SAMPLE_BITS 502
@@ -90,4 +98,29 @@
#define SOF_TKN_MEDIATEK_AFE_RATE 1600
#define SOF_TKN_MEDIATEK_AFE_CH 1601
#define SOF_TKN_MEDIATEK_AFE_FORMAT 1602
+#define SOF_TKN_MIXER_TYPE 1700
+#define SOF_TKN_AMD_ACPDMIC_RATE 1800
+#define SOF_TKN_AMD_ACPDMIC_CH 1801
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE 1900
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH 1901
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT 1902
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CHANNELS 1903
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP 1904
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG 1905
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE 1906
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG 1907
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_SAMPLE_TYPE 1908
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE 1930
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH 1931
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT 1932
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CHANNELS 1933
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP 1934
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG 1935
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE 1936
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG 1937
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_SAMPLE_TYPE 1938
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IBS 1970
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OBS 1971
+#define SOF_TKN_CAVS_AUDIO_FORMAT_DMA_BUFFER_SIZE 1972
+#define SOF_TKN_INTEL_COPIER_NODE_TYPE 1980
#endif
diff --git a/libc/kernel/uapi/sound/usb_stream.h b/libc/kernel/uapi/sound/usb_stream.h
index bb7fe80..ac87c31 100644
--- a/libc/kernel/uapi/sound/usb_stream.h
+++ b/libc/kernel/uapi/sound/usb_stream.h
@@ -49,7 +49,7 @@
unsigned inpacket_split_at;
unsigned next_inpacket_split;
unsigned next_inpacket_split_at;
- struct usb_stream_packet inpacket[0];
+ struct usb_stream_packet inpacket[];
};
enum usb_stream_state {
usb_stream_invalid,
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 7397b68..dc1b6f6 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -680,28 +680,28 @@
nftw64; # introduced=21
nice;
nrand48;
- ns_format_ttl; # arm64 x86_64 introduced=22
- ns_get16; # arm64 x86_64 introduced=22
- ns_get32; # arm64 x86_64 introduced=22
- ns_initparse; # arm64 x86_64 introduced=22
- ns_makecanon; # arm64 x86_64 introduced=22
- ns_msg_getflag; # arm64 x86_64 introduced=22
- ns_name_compress; # arm64 x86_64 introduced=22
- ns_name_ntol; # arm64 x86_64 introduced=22
- ns_name_ntop; # arm64 x86_64 introduced=22
- ns_name_pack; # arm64 x86_64 introduced=22
- ns_name_pton; # arm64 x86_64 introduced=22
- ns_name_rollback; # arm64 x86_64 introduced=22
- ns_name_skip; # arm64 x86_64 introduced=22
- ns_name_uncompress; # arm64 x86_64 introduced=22
- ns_name_unpack; # arm64 x86_64 introduced=22
- ns_parserr; # arm64 x86_64 introduced=22
- ns_put16; # arm64 x86_64 introduced=22
- ns_put32; # arm64 x86_64 introduced=22
- ns_samename; # arm64 x86_64 introduced=22
- ns_skiprr; # arm64 x86_64 introduced=22
- ns_sprintrr; # arm64 x86_64 introduced=22
- ns_sprintrrf; # arm64 x86_64 introduced=22
+ ns_format_ttl; # arm64 x86_64 riscv64 introduced=22
+ ns_get16; # arm64 x86_64 riscv64 introduced=22
+ ns_get32; # arm64 x86_64 riscv64 introduced=22
+ ns_initparse; # arm64 x86_64 riscv64 introduced=22
+ ns_makecanon; # arm64 x86_64 riscv64 introduced=22
+ ns_msg_getflag; # arm64 x86_64 riscv64 introduced=22
+ ns_name_compress; # arm64 x86_64 riscv64 introduced=22
+ ns_name_ntol; # arm64 x86_64 riscv64 introduced=22
+ ns_name_ntop; # arm64 x86_64 riscv64 introduced=22
+ ns_name_pack; # arm64 x86_64 riscv64 introduced=22
+ ns_name_pton; # arm64 x86_64 riscv64 introduced=22
+ ns_name_rollback; # arm64 x86_64 riscv64 introduced=22
+ ns_name_skip; # arm64 x86_64 riscv64 introduced=22
+ ns_name_uncompress; # arm64 x86_64 riscv64 introduced=22
+ ns_name_unpack; # arm64 x86_64 riscv64 introduced=22
+ ns_parserr; # arm64 x86_64 riscv64 introduced=22
+ ns_put16; # arm64 x86_64 riscv64 introduced=22
+ ns_put32; # arm64 x86_64 riscv64 introduced=22
+ ns_samename; # arm64 x86_64 riscv64 introduced=22
+ ns_skiprr; # arm64 x86_64 riscv64 introduced=22
+ ns_sprintrr; # arm64 x86_64 riscv64 introduced=22
+ ns_sprintrrf; # arm64 x86_64 riscv64 introduced=22
nsdispatch;
ntohl; # introduced=21
ntohs; # introduced=21
@@ -740,7 +740,7 @@
pread;
pread64; # introduced-arm=12 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
printf;
- prlimit; # arm64 x86_64
+ prlimit; # arm64 x86_64 riscv64
prlimit64; # introduced=21
process_vm_readv; # introduced=23
process_vm_writev; # introduced=23
@@ -1449,7 +1449,7 @@
___tls_get_addr; # x86
__aeabi_read_tp; # arm
__res_randomid;
- __tls_get_addr; # arm x86_64
+ __tls_get_addr; # arm riscv64 x86_64
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
@@ -1576,6 +1576,14 @@
pwritev64v2;
} LIBC_S;
+LIBC_U { # introduced=UpsideDownCake
+ global:
+ __freadahead;
+ close_range;
+ copy_file_range;
+ memset_explicit;
+} LIBC_T;
+
LIBC_PRIVATE {
global:
__accept4; # arm x86
diff --git a/libc/libstdc++.map.txt b/libc/libstdc++.map.txt
index bb7040f..8af3b91 100644
--- a/libc/libstdc++.map.txt
+++ b/libc/libstdc++.map.txt
@@ -7,12 +7,12 @@
_ZdlPvRKSt9nothrow_t; # weak
_Znaj; # arm x86 weak
_ZnajRKSt9nothrow_t; # arm x86 weak
- _Znam; # arm64 x86_64 weak
- _ZnamRKSt9nothrow_t; # arm64 x86_64 weak
+ _Znam; # arm64 x86_64 riscv64 weak
+ _ZnamRKSt9nothrow_t; # arm64 x86_64 riscv64 weak
_Znwj; # arm x86 weak
_ZnwjRKSt9nothrow_t; # arm x86 weak
- _Znwm; # arm64 x86_64 weak
- _ZnwmRKSt9nothrow_t; # arm64 x86_64 weak
+ _Znwm; # arm64 x86_64 riscv64 weak
+ _ZnwmRKSt9nothrow_t; # arm64 x86_64 riscv64 weak
__cxa_guard_abort;
__cxa_guard_acquire;
__cxa_guard_release;
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index 7ff3db2..e7a157e 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -64,6 +64,7 @@
"malloc_debug.cpp",
"PointerData.cpp",
"RecordData.cpp",
+ "Unreachable.cpp",
"UnwindBacktrace.cpp",
],
@@ -73,6 +74,7 @@
"libasync_safe",
"libbase",
"libc_malloc_debug_backtrace",
+ "libmemunreachable",
],
shared_libs: [
@@ -120,6 +122,7 @@
cc_test {
name: "malloc_debug_unit_tests",
test_suites: ["device-tests"],
+ isolated: true,
srcs: [
"tests/backtrace_fake.cpp",
@@ -179,7 +182,6 @@
shared_libs: [
"libbase",
- "libbacktrace",
"liblog",
"libunwindstack",
],
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index 11887e2..6a81277 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -70,17 +70,34 @@
const std::unordered_map<std::string, Config::OptionInfo> Config::kOptions = {
{
- "guard", {FRONT_GUARD | REAR_GUARD | TRACK_ALLOCS, &Config::SetGuard},
+ "guard",
+ {FRONT_GUARD | REAR_GUARD | TRACK_ALLOCS, &Config::SetGuard},
},
{
- "front_guard", {FRONT_GUARD | TRACK_ALLOCS, &Config::SetFrontGuard},
+ "front_guard",
+ {FRONT_GUARD | TRACK_ALLOCS, &Config::SetFrontGuard},
},
{
- "rear_guard", {REAR_GUARD | TRACK_ALLOCS, &Config::SetRearGuard},
+ "rear_guard",
+ {REAR_GUARD | TRACK_ALLOCS, &Config::SetRearGuard},
},
{
- "backtrace", {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktrace},
+ "backtrace_size",
+ {BACKTRACE_SPECIFIC_SIZES, &Config::SetBacktraceSize},
+ },
+ {
+ "backtrace_min_size",
+ {BACKTRACE_SPECIFIC_SIZES, &Config::SetBacktraceMinSize},
+ },
+ {
+ "backtrace_max_size",
+ {BACKTRACE_SPECIFIC_SIZES, &Config::SetBacktraceMaxSize},
+ },
+
+ {
+ "backtrace",
+ {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktrace},
},
{
"backtrace_enable_on_signal",
@@ -88,55 +105,74 @@
},
{
- "backtrace_dump_on_exit", {0, &Config::SetBacktraceDumpOnExit},
+ "backtrace_dump_on_exit",
+ {0, &Config::SetBacktraceDumpOnExit},
},
{
- "backtrace_dump_prefix", {0, &Config::SetBacktraceDumpPrefix},
+ "backtrace_dump_prefix",
+ {0, &Config::SetBacktraceDumpPrefix},
},
{
- "backtrace_full", {BACKTRACE_FULL, &Config::VerifyValueEmpty},
+ "backtrace_full",
+ {BACKTRACE_FULL, &Config::VerifyValueEmpty},
},
{
- "fill", {FILL_ON_ALLOC | FILL_ON_FREE, &Config::SetFill},
+ "fill",
+ {FILL_ON_ALLOC | FILL_ON_FREE, &Config::SetFill},
},
{
- "fill_on_alloc", {FILL_ON_ALLOC, &Config::SetFillOnAlloc},
+ "fill_on_alloc",
+ {FILL_ON_ALLOC, &Config::SetFillOnAlloc},
},
{
- "fill_on_free", {FILL_ON_FREE, &Config::SetFillOnFree},
+ "fill_on_free",
+ {FILL_ON_FREE, &Config::SetFillOnFree},
},
{
- "expand_alloc", {EXPAND_ALLOC, &Config::SetExpandAlloc},
+ "expand_alloc",
+ {EXPAND_ALLOC, &Config::SetExpandAlloc},
},
{
- "free_track", {FREE_TRACK | FILL_ON_FREE | TRACK_ALLOCS, &Config::SetFreeTrack},
+ "free_track",
+ {FREE_TRACK | FILL_ON_FREE | TRACK_ALLOCS, &Config::SetFreeTrack},
},
{
- "free_track_backtrace_num_frames", {0, &Config::SetFreeTrackBacktraceNumFrames},
+ "free_track_backtrace_num_frames",
+ {0, &Config::SetFreeTrackBacktraceNumFrames},
},
{
- "leak_track", {LEAK_TRACK | TRACK_ALLOCS, &Config::VerifyValueEmpty},
+ "leak_track",
+ {LEAK_TRACK | TRACK_ALLOCS, &Config::VerifyValueEmpty},
},
{
- "record_allocs", {RECORD_ALLOCS, &Config::SetRecordAllocs},
+ "record_allocs",
+ {RECORD_ALLOCS, &Config::SetRecordAllocs},
},
{
- "record_allocs_file", {0, &Config::SetRecordAllocsFile},
+ "record_allocs_file",
+ {0, &Config::SetRecordAllocsFile},
},
{
- "verify_pointers", {TRACK_ALLOCS, &Config::VerifyValueEmpty},
+ "verify_pointers",
+ {TRACK_ALLOCS, &Config::VerifyValueEmpty},
},
{
- "abort_on_error", {ABORT_ON_ERROR, &Config::VerifyValueEmpty},
+ "abort_on_error",
+ {ABORT_ON_ERROR, &Config::VerifyValueEmpty},
},
{
- "verbose", {VERBOSE, &Config::VerifyValueEmpty},
+ "verbose",
+ {VERBOSE, &Config::VerifyValueEmpty},
+ },
+ {
+ "check_unreachable_on_signal",
+ {CHECK_UNREACHABLE_ON_SIGNAL, &Config::VerifyValueEmpty},
},
};
@@ -274,6 +310,23 @@
return true;
}
+bool Config::SetBacktraceSize(const std::string& option, const std::string& value) {
+ if (!ParseValue(option, value, 1, SIZE_MAX, &backtrace_min_size_bytes_)) {
+ return false;
+ }
+ backtrace_max_size_bytes_ = backtrace_min_size_bytes_;
+
+ return true;
+}
+
+bool Config::SetBacktraceMinSize(const std::string& option, const std::string& value) {
+ return ParseValue(option, value, 1, SIZE_MAX, &backtrace_min_size_bytes_);
+}
+
+bool Config::SetBacktraceMaxSize(const std::string& option, const std::string& value) {
+ return ParseValue(option, value, 1, SIZE_MAX, &backtrace_max_size_bytes_);
+}
+
bool Config::SetExpandAlloc(const std::string& option, const std::string& value) {
return ParseValue(option, value, DEFAULT_EXPAND_BYTES, 1, MAX_EXPAND_BYTES, &expand_alloc_bytes_);
}
@@ -380,6 +433,9 @@
backtrace_enabled_ = false;
backtrace_dump_on_exit_ = false;
backtrace_dump_prefix_ = DEFAULT_BACKTRACE_DUMP_PREFIX;
+ backtrace_min_size_bytes_ = 0;
+ backtrace_max_size_bytes_ = SIZE_MAX;
+ check_unreachable_signal_ = SIGRTMAX - 16;
// Process each option name we can find.
std::string option;
diff --git a/libc/malloc_debug/Config.h b/libc/malloc_debug/Config.h
index 1b5c748..ef1d2a9 100644
--- a/libc/malloc_debug/Config.h
+++ b/libc/malloc_debug/Config.h
@@ -46,6 +46,8 @@
constexpr uint64_t BACKTRACE_FULL = 0x400;
constexpr uint64_t ABORT_ON_ERROR = 0x800;
constexpr uint64_t VERBOSE = 0x1000;
+constexpr uint64_t CHECK_UNREACHABLE_ON_SIGNAL = 0x2000;
+constexpr uint64_t BACKTRACE_SPECIFIC_SIZES = 0x4000;
// In order to guarantee posix compliance, set the minimum alignment
// to 8 bytes for 32 bit systems and 16 bytes for 64 bit systems.
@@ -89,10 +91,15 @@
uint8_t fill_alloc_value() const { return fill_alloc_value_; }
uint8_t fill_free_value() const { return fill_free_value_; }
+ size_t backtrace_min_size_bytes() const { return backtrace_min_size_bytes_; }
+ size_t backtrace_max_size_bytes() const { return backtrace_max_size_bytes_; }
+
int record_allocs_signal() const { return record_allocs_signal_; }
size_t record_allocs_num_entries() const { return record_allocs_num_entries_; }
const std::string& record_allocs_file() const { return record_allocs_file_; }
+ int check_unreachable_signal() const { return check_unreachable_signal_; }
+
private:
struct OptionInfo {
uint64_t option;
@@ -118,6 +125,10 @@
bool SetBacktraceDumpOnExit(const std::string& option, const std::string& value);
bool SetBacktraceDumpPrefix(const std::string& option, const std::string& value);
+ bool SetBacktraceSize(const std::string& option, const std::string& value);
+ bool SetBacktraceMinSize(const std::string& option, const std::string& value);
+ bool SetBacktraceMaxSize(const std::string& option, const std::string& value);
+
bool SetExpandAlloc(const std::string& option, const std::string& value);
bool SetFreeTrack(const std::string& option, const std::string& value);
@@ -142,6 +153,8 @@
size_t backtrace_frames_ = 0;
bool backtrace_dump_on_exit_ = false;
std::string backtrace_dump_prefix_;
+ size_t backtrace_min_size_bytes_ = 0;
+ size_t backtrace_max_size_bytes_ = 0;
size_t fill_on_alloc_bytes_ = 0;
size_t fill_on_free_bytes_ = 0;
@@ -160,4 +173,6 @@
uint8_t fill_free_value_;
uint8_t front_guard_value_;
uint8_t rear_guard_value_;
+
+ int check_unreachable_signal_ = 0;
};
diff --git a/libc/malloc_debug/MapData.cpp b/libc/malloc_debug/MapData.cpp
index ded81a2..b22c109 100644
--- a/libc/malloc_debug/MapData.cpp
+++ b/libc/malloc_debug/MapData.cpp
@@ -210,7 +210,7 @@
}
}
}
- *rel_pc = pc - entry->start + entry->load_bias;
+ *rel_pc = pc - entry->start + entry->offset + entry->load_bias;
}
return entry;
}
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index b982c0a..5ab2232 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -35,6 +35,7 @@
#include <sys/types.h>
#include <unistd.h>
+#include <functional>
#include <mutex>
#include <string>
#include <unordered_map>
@@ -135,7 +136,22 @@
return true;
}
-size_t PointerData::AddBacktrace(size_t num_frames) {
+static inline bool ShouldBacktraceAllocSize(size_t size_bytes) {
+ static bool only_backtrace_specific_sizes =
+ g_debug->config().options() & BACKTRACE_SPECIFIC_SIZES;
+ if (!only_backtrace_specific_sizes) {
+ return true;
+ }
+ static size_t min_size_bytes = g_debug->config().backtrace_min_size_bytes();
+ static size_t max_size_bytes = g_debug->config().backtrace_max_size_bytes();
+ return size_bytes >= min_size_bytes && size_bytes <= max_size_bytes;
+}
+
+size_t PointerData::AddBacktrace(size_t num_frames, size_t size_bytes) {
+ if (!ShouldBacktraceAllocSize(size_bytes)) {
+ return kBacktraceEmptyIndex;
+ }
+
std::vector<uintptr_t> frames;
std::vector<unwindstack::FrameData> frames_info;
if (g_debug->config().options() & BACKTRACE_FULL) {
@@ -148,14 +164,14 @@
if (num_frames == 0) {
return kBacktraceEmptyIndex;
}
+ frames.resize(num_frames);
}
- FrameKeyType key{.num_frames = num_frames, .frames = frames.data()};
+ FrameKeyType key{.num_frames = frames.size(), .frames = frames.data()};
size_t hash_index;
std::lock_guard<std::mutex> frame_guard(frame_mutex_);
auto entry = key_to_index_.find(key);
if (entry == key_to_index_.end()) {
- frames.resize(num_frames);
hash_index = cur_hash_index_++;
key.frames = frames.data();
key_to_index_.emplace(key, hash_index);
@@ -195,40 +211,41 @@
}
void PointerData::Add(const void* ptr, size_t pointer_size) {
- uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
size_t hash_index = 0;
if (backtrace_enabled_) {
- hash_index = AddBacktrace(g_debug->config().backtrace_frames());
+ hash_index = AddBacktrace(g_debug->config().backtrace_frames(), pointer_size);
}
std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
- pointers_[pointer] = PointerInfoType{PointerInfoType::GetEncodedSize(pointer_size), hash_index};
+ uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+ pointers_[mangled_ptr] =
+ PointerInfoType{PointerInfoType::GetEncodedSize(pointer_size), hash_index};
}
void PointerData::Remove(const void* ptr) {
- uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
size_t hash_index;
{
std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
- auto entry = pointers_.find(pointer);
+ uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+ auto entry = pointers_.find(mangled_ptr);
if (entry == pointers_.end()) {
// Attempt to remove unknown pointer.
- error_log("No tracked pointer found for 0x%" PRIxPTR, pointer);
+ error_log("No tracked pointer found for 0x%" PRIxPTR, DemanglePointer(mangled_ptr));
return;
}
hash_index = entry->second.hash_index;
- pointers_.erase(pointer);
+ pointers_.erase(mangled_ptr);
}
RemoveBacktrace(hash_index);
}
size_t PointerData::GetFrames(const void* ptr, uintptr_t* frames, size_t max_frames) {
- uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
size_t hash_index;
{
std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
- auto entry = pointers_.find(pointer);
+ uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+ auto entry = pointers_.find(mangled_ptr);
if (entry == pointers_.end()) {
return 0;
}
@@ -274,7 +291,8 @@
void PointerData::LogFreeError(const FreePointerInfoType& info, size_t max_cmp_bytes) {
error_log(LOG_DIVIDER);
- uint8_t* memory = reinterpret_cast<uint8_t*>(info.pointer);
+ uintptr_t pointer = DemanglePointer(info.mangled_ptr);
+ uint8_t* memory = reinterpret_cast<uint8_t*>(pointer);
error_log("+++ ALLOCATION %p USED AFTER FREE", memory);
uint8_t fill_free_value = g_debug->config().fill_free_value();
for (size_t i = 0; i < max_cmp_bytes; i++) {
@@ -296,13 +314,14 @@
void PointerData::VerifyFreedPointer(const FreePointerInfoType& info) {
size_t usable_size;
+ uintptr_t pointer = DemanglePointer(info.mangled_ptr);
if (g_debug->HeaderEnabled()) {
// Check to see if the tag data has been damaged.
- Header* header = g_debug->GetHeader(reinterpret_cast<const void*>(info.pointer));
+ Header* header = g_debug->GetHeader(reinterpret_cast<const void*>(pointer));
if (header->tag != DEBUG_FREE_TAG) {
error_log(LOG_DIVIDER);
- error_log("+++ ALLOCATION 0x%" PRIxPTR " HAS CORRUPTED HEADER TAG 0x%x AFTER FREE",
- info.pointer, header->tag);
+ error_log("+++ ALLOCATION 0x%" PRIxPTR " HAS CORRUPTED HEADER TAG 0x%x AFTER FREE", pointer,
+ header->tag);
error_log(LOG_DIVIDER);
if (g_debug->config().options() & ABORT_ON_ERROR) {
abort();
@@ -314,14 +333,14 @@
}
usable_size = header->usable_size;
} else {
- usable_size = g_dispatch->malloc_usable_size(reinterpret_cast<const void*>(info.pointer));
+ usable_size = g_dispatch->malloc_usable_size(reinterpret_cast<const void*>(pointer));
}
size_t bytes = (usable_size < g_debug->config().fill_on_free_bytes())
? usable_size
: g_debug->config().fill_on_free_bytes();
size_t max_cmp_bytes = bytes;
- const uint8_t* memory = reinterpret_cast<const uint8_t*>(info.pointer);
+ const uint8_t* memory = reinterpret_cast<const uint8_t*>(pointer);
while (bytes > 0) {
size_t bytes_to_cmp = (bytes < g_cmp_mem.size()) ? bytes : g_cmp_mem.size();
if (memcmp(memory, g_cmp_mem.data(), bytes_to_cmp) != 0) {
@@ -332,13 +351,11 @@
}
}
-void* PointerData::AddFreed(const void* ptr) {
- uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
-
+void* PointerData::AddFreed(const void* ptr, size_t size_bytes) {
size_t hash_index = 0;
size_t num_frames = g_debug->config().free_track_backtrace_num_frames();
if (num_frames) {
- hash_index = AddBacktrace(num_frames);
+ hash_index = AddBacktrace(num_frames, size_bytes);
}
void* last = nullptr;
@@ -348,10 +365,11 @@
free_pointers_.pop_front();
VerifyFreedPointer(info);
RemoveBacktrace(info.hash_index);
- last = reinterpret_cast<void*>(info.pointer);
+ last = reinterpret_cast<void*>(DemanglePointer(info.mangled_ptr));
}
- free_pointers_.emplace_back(FreePointerInfoType{pointer, hash_index});
+ uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+ free_pointers_.emplace_back(FreePointerInfoType{mangled_ptr, hash_index});
return last;
}
@@ -361,7 +379,7 @@
uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
std::lock_guard<std::mutex> freed_guard(free_pointer_mutex_);
for (const auto& info : free_pointers_) {
- if (info.pointer == pointer) {
+ if (DemanglePointer(info.mangled_ptr) == pointer) {
hash_index = info.hash_index;
break;
}
@@ -388,6 +406,7 @@
for (const auto& entry : pointers_) {
FrameInfoType* frame_info = nullptr;
std::vector<unwindstack::FrameData>* backtrace_info = nullptr;
+ uintptr_t pointer = DemanglePointer(entry.first);
size_t hash_index = entry.second.hash_index;
if (hash_index > kBacktraceEmptyIndex) {
auto frame_entry = frames_.find(hash_index);
@@ -397,7 +416,7 @@
// occurs after the hash_index and frame data have been added.
// When removing a pointer, the pointer is deleted before the frame
// data.
- error_log("Pointer 0x%" PRIxPTR " hash_index %zu does not exist.", entry.first, hash_index);
+ error_log("Pointer 0x%" PRIxPTR " hash_index %zu does not exist.", pointer, hash_index);
} else {
frame_info = &frame_entry->second;
}
@@ -405,7 +424,7 @@
if (g_debug->config().options() & BACKTRACE_FULL) {
auto backtrace_entry = backtraces_info_.find(hash_index);
if (backtrace_entry == backtraces_info_.end()) {
- error_log("Pointer 0x%" PRIxPTR " hash_index %zu does not exist.", entry.first, hash_index);
+ error_log("Pointer 0x%" PRIxPTR " hash_index %zu does not exist.", pointer, hash_index);
} else {
backtrace_info = &backtrace_entry->second;
}
@@ -415,7 +434,7 @@
continue;
}
- list->emplace_back(ListInfoType{entry.first, 1, entry.second.RealSize(),
+ list->emplace_back(ListInfoType{pointer, 1, entry.second.RealSize(),
entry.second.ZygoteChildAlloc(), frame_info, backtrace_info});
}
@@ -550,9 +569,9 @@
}
bool PointerData::Exists(const void* ptr) {
- uintptr_t pointer = reinterpret_cast<uintptr_t>(ptr);
std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
- return pointers_.count(pointer) != 0;
+ uintptr_t mangled_ptr = ManglePointer(reinterpret_cast<uintptr_t>(ptr));
+ return pointers_.count(mangled_ptr) != 0;
}
void PointerData::DumpLiveToFile(int fd) {
@@ -637,3 +656,10 @@
free_pointer_mutex_.try_lock();
free_pointer_mutex_.unlock();
}
+
+void PointerData::IteratePointers(std::function<void(uintptr_t pointer)> fn) {
+ std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
+ for (const auto entry : pointers_) {
+ fn(DemanglePointer(entry.first));
+ }
+}
diff --git a/libc/malloc_debug/PointerData.h b/libc/malloc_debug/PointerData.h
index 92d2653..3194bab 100644
--- a/libc/malloc_debug/PointerData.h
+++ b/libc/malloc_debug/PointerData.h
@@ -33,6 +33,7 @@
#include <atomic>
#include <deque>
+#include <functional>
#include <mutex>
#include <string>
#include <unordered_map>
@@ -99,7 +100,7 @@
};
struct FreePointerInfoType {
- uintptr_t pointer;
+ uintptr_t mangled_ptr;
size_t hash_index;
};
@@ -134,17 +135,15 @@
void PostForkParent();
void PostForkChild();
- static size_t AddBacktrace(size_t num_frames);
+ static void IteratePointers(std::function<void(uintptr_t pointer)> fn);
+
+ static size_t AddBacktrace(size_t num_frames, size_t size_bytes);
static void RemoveBacktrace(size_t hash_index);
static void Add(const void* pointer, size_t size);
static void Remove(const void* pointer);
- typedef std::unordered_map<uintptr_t, PointerInfoType>::iterator iterator;
- static iterator begin() { return pointers_.begin(); }
- static iterator end() { return pointers_.end(); }
-
- static void* AddFreed(const void* pointer);
+ static void* AddFreed(const void* pointer, size_t size_bytes);
static void LogFreeError(const FreePointerInfoType& info, size_t usable_size);
static void LogFreeBacktrace(const void* ptr);
static void VerifyFreedPointer(const FreePointerInfoType& info);
@@ -162,6 +161,12 @@
static bool Exists(const void* pointer);
private:
+ // Only keep mangled pointers in internal data structures. This avoids
+ // problems where libmemunreachable finds these pointers and thinks they
+ // are not unreachable.
+ static inline uintptr_t ManglePointer(uintptr_t pointer) { return pointer ^ UINTPTR_MAX; }
+ static inline uintptr_t DemanglePointer(uintptr_t pointer) { return pointer ^ UINTPTR_MAX; }
+
static std::string GetHashString(uintptr_t* frames, size_t num_frames);
static void LogBacktrace(size_t hash_index);
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index 662f5f8..3667624 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -114,7 +114,7 @@
option will not add a special header.
As of P, this option will also enable dumping backtrace heap data to a
-file when the process receives the signal SIGRTMAX - 17 ( which is 47 on most
+file when the process receives the signal SIGRTMAX - 17 ( which is 47 on
Android devices). The format of this dumped data is the same format as
that dumped when running am dumpheap -n. The default is to dump this data
to the file /data/local/tmp/backtrace\_heap.**PID**.txt. This is useful when
@@ -127,7 +127,7 @@
### backtrace\_enable\_on\_signal[=MAX\_FRAMES]
Enable capturing the backtrace of each allocation site. If the
backtrace capture is toggled when the process receives the signal
-SIGRTMAX - 19 (which is 45 on most Android devices). When this
+SIGRTMAX - 19 (which is 45 on Android devices). When this
option is used alone, backtrace capture starts out disabled until the signal
is received. If both this option and the backtrace option are set, then
backtrace capture is enabled until the signal is received.
@@ -160,11 +160,69 @@
on the signal will be backtrace\_dump\_prefix.**PID**.txt. The filename chosen
when the program exits will be backtrace\_dump\_prefix.**PID**.exit.txt.
+### backtrace\_min\_size=ALLOCATION\_SIZE\_BYTES
+As of U, setting this in combination with the backtrace option means
+that only allocations of a size greater than or equal to
+**ALLOCATION\_SIZE\_BYTES** will be backtraced. When used in combination
+with the backtrace\_max\_size option, then allocations greater than or
+equal to backtrace\_min\_size and less than or equal to
+backtrace\_max\_size will be backtraced. The backtrace\_size option
+overrides this option, and should not be used at the same time.
+
+This option can also be used in combination with other tools such
+as [libmemunreachable](https://android.googlesource.com/platform/system/memory/libmemunreachable/+/master/README.md)
+to only get backtraces for sizes of allocations listed as being leaked.
+
+### backtrace\_max\_size=ALLOCATION\_SIZE\_BYTES
+As of U, setting this in combination with the backtrace option means
+that only allocations of a size less than or equal to
+**ALLOCATION\_SIZE\_BYTES** will be backtraced. When used in combination
+with the backtrace\_min\_size option, then allocations greater than or
+equal to backtrace\_min\_size and less than or equal to
+backtrace\_max\_size will be backtraced. The backtrace\_size option
+overrides this option, and should not be used at the same time.
+
+This option can also be used in combination with other tools such
+as [libmemunreachable](https://android.googlesource.com/platform/system/memory/libmemunreachable/+/master/README.md)
+to only get backtraces for sizes of allocations listed as being leaked.
+
+### backtrace\_size=ALLOCATION\_SIZE\_BYTES
+As of U, setting this in combination with the backtrace option means
+that only allocations of size **ALLOCATION\_SIZE\_BYTES** will be backtraced.
+This option overrides the backtrace\_min\_size and the backtrace\_max\_size.
+
+This option can also be used in combination with other tools such
+as [libmemunreachable](https://android.googlesource.com/platform/system/memory/libmemunreachable/+/master/README.md)
+to only get backtraces for sizes of allocations listed as being leaked.
+
### backtrace\_full
As of Q, any time that a backtrace is gathered, a different algorithm is used
that is extra thorough and can unwind through Java frames. This will run
slower than the normal backtracing function.
+### check\_unreachable\_on\_signal
+As of Android U, this option will trigger a check for unreachable memory
+in a process. Specifically, if the signal SIGRTMAX - 16 (which is 48 on
+Android devices). The best way to see the exact signal being used is to
+enable the verbose option then look at the log for the message:
+
+ Run: 'kill -48 <PID>' to check for unreachable memory.
+
+When the signal is received, the actual unreachable check only triggers
+on the next allocation that happens in the process (malloc/free, etc).
+
+If a process is not doing any allocations, it can be forced to trigger when
+running:
+
+ debuggerd -b <PID>
+
+**NOTE**: The unreachable check can fail for protected processes, so it
+might be necessary to run:
+
+ setenforce 0
+
+To get the unreachable data.
+
### fill\_on\_alloc[=MAX\_FILLED\_BYTES]
Any allocation routine, other than calloc, will result in the allocation being
filled with the value 0xeb. When doing a realloc to a larger size, the bytes
@@ -270,7 +328,7 @@
### record\_allocs[=TOTAL\_ENTRIES]
Keep track of every allocation/free made on every thread and dump them
-to a file when the signal SIGRTMAX - 18 (which is 46 on most Android devices)
+to a file when the signal SIGRTMAX - 18 (which is 46 on Android devices)
is received.
If TOTAL\_ENTRIES is set, then it indicates the total number of
diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp
index 5c550c0..a829a09 100644
--- a/libc/malloc_debug/RecordData.cpp
+++ b/libc/malloc_debug/RecordData.cpp
@@ -48,44 +48,44 @@
RecordEntry::RecordEntry() : tid_(gettid()) {
}
-std::string ThreadCompleteEntry::GetString() const {
- return android::base::StringPrintf("%d: thread_done 0x0\n", tid_);
+bool ThreadCompleteEntry::Write(int fd) const {
+ return dprintf(fd, "%d: thread_done 0x0\n", tid_) > 0;
}
AllocEntry::AllocEntry(void* pointer) : pointer_(pointer) {}
MallocEntry::MallocEntry(void* pointer, size_t size) : AllocEntry(pointer), size_(size) {}
-std::string MallocEntry::GetString() const {
- return android::base::StringPrintf("%d: malloc %p %zu\n", tid_, pointer_, size_);
+bool MallocEntry::Write(int fd) const {
+ return dprintf(fd, "%d: malloc %p %zu\n", tid_, pointer_, size_) > 0;
}
FreeEntry::FreeEntry(void* pointer) : AllocEntry(pointer) {}
-std::string FreeEntry::GetString() const {
- return android::base::StringPrintf("%d: free %p\n", tid_, pointer_);
+bool FreeEntry::Write(int fd) const {
+ return dprintf(fd, "%d: free %p\n", tid_, pointer_) > 0;
}
CallocEntry::CallocEntry(void* pointer, size_t nmemb, size_t size)
: MallocEntry(pointer, size), nmemb_(nmemb) {}
-std::string CallocEntry::GetString() const {
- return android::base::StringPrintf("%d: calloc %p %zu %zu\n", tid_, pointer_, nmemb_, size_);
+bool CallocEntry::Write(int fd) const {
+ return dprintf(fd, "%d: calloc %p %zu %zu\n", tid_, pointer_, nmemb_, size_) > 0;
}
ReallocEntry::ReallocEntry(void* pointer, size_t size, void* old_pointer)
: MallocEntry(pointer, size), old_pointer_(old_pointer) {}
-std::string ReallocEntry::GetString() const {
- return android::base::StringPrintf("%d: realloc %p %p %zu\n", tid_, pointer_, old_pointer_, size_);
+bool ReallocEntry::Write(int fd) const {
+ return dprintf(fd, "%d: realloc %p %p %zu\n", tid_, pointer_, old_pointer_, size_) > 0;
}
// aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
MemalignEntry::MemalignEntry(void* pointer, size_t size, size_t alignment)
: MallocEntry(pointer, size), alignment_(alignment) {}
-std::string MemalignEntry::GetString() const {
- return android::base::StringPrintf("%d: memalign %p %zu %zu\n", tid_, pointer_, alignment_, size_);
+bool MemalignEntry::Write(int fd) const {
+ return dprintf(fd, "%d: memalign %p %zu %zu\n", tid_, pointer_, alignment_, size_) > 0;
}
struct ThreadData {
@@ -112,59 +112,37 @@
}
}
-static void RecordDump(int, siginfo_t*, void*) {
- // It's not necessarily safe to do the dump here, instead wait for the
- // next allocation call to do the dump.
- g_debug->record->SetToDump();
+RecordData* RecordData::record_obj_ = nullptr;
+
+void RecordData::WriteData(int, siginfo_t*, void*) {
+ // Dump from here, the function must not allocate so this is safe.
+ record_obj_->WriteEntries();
}
-void RecordData::Dump() {
- std::lock_guard<std::mutex> lock(dump_lock_);
-
- // Make it so that no more entries can be added while dumping.
- unsigned int last_entry_index = cur_index_.exchange(static_cast<unsigned int>(num_entries_));
- if (dump_ == false) {
- // Multiple Dump() calls from different threads, and we lost. Do nothing.
+void RecordData::WriteEntries() {
+ std::lock_guard<std::mutex> entries_lock(entries_lock_);
+ if (cur_index_ == 0) {
+ info_log("No alloc entries to write.");
return;
}
- // cur_index_ keeps getting incremented even if we hit the num_entries_.
- // If that happens, cap the entries to dump by num_entries_.
- if (last_entry_index > num_entries_) {
- last_entry_index = num_entries_;
- }
-
int dump_fd =
open(dump_file_.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW, 0755);
- if (dump_fd != -1) {
- for (size_t i = 0; i < last_entry_index; i++) {
- std::string line = entries_[i]->GetString();
- ssize_t bytes = write(dump_fd, line.c_str(), line.length());
- if (bytes == -1 || static_cast<size_t>(bytes) != line.length()) {
- error_log("Failed to write record alloc information: %s", strerror(errno));
- // Free all of the rest of the errors, we don't have any way
- // to dump a partial list of the entries.
- for (i++; i < last_entry_index; i++) {
- delete entries_[i];
- entries_[i] = nullptr;
- }
- break;
- }
- delete entries_[i];
- entries_[i] = nullptr;
- }
- close(dump_fd);
-
- // Mark the entries dumped.
- cur_index_ = 0U;
- } else {
+ if (dump_fd == -1) {
error_log("Cannot create record alloc file %s: %s", dump_file_.c_str(), strerror(errno));
- // Since we couldn't create the file, reset the entries dumped back
- // to the original value.
- cur_index_ = last_entry_index;
+ return;
}
- dump_ = false;
+ for (size_t i = 0; i < cur_index_; i++) {
+ if (!entries_[i]->Write(dump_fd)) {
+ error_log("Failed to write record alloc information: %s", strerror(errno));
+ break;
+ }
+ }
+ close(dump_fd);
+
+ // Mark the entries dumped.
+ cur_index_ = 0U;
}
RecordData::RecordData() {
@@ -172,8 +150,9 @@
}
bool RecordData::Initialize(const Config& config) {
+ record_obj_ = this;
struct sigaction64 dump_act = {};
- dump_act.sa_sigaction = RecordDump;
+ dump_act.sa_sigaction = RecordData::WriteData;
dump_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
if (sigaction64(config.record_allocs_signal(), &dump_act, nullptr) != 0) {
error_log("Unable to set up record dump signal function: %s", strerror(errno));
@@ -186,24 +165,27 @@
config.record_allocs_signal(), getpid());
}
- num_entries_ = config.record_allocs_num_entries();
- entries_ = new const RecordEntry*[num_entries_];
- cur_index_ = 0;
- dump_ = false;
+ entries_.resize(config.record_allocs_num_entries());
+ cur_index_ = 0U;
dump_file_ = config.record_allocs_file();
return true;
}
RecordData::~RecordData() {
- delete[] entries_;
pthread_key_delete(key_);
}
void RecordData::AddEntryOnly(const RecordEntry* entry) {
- unsigned int entry_index = cur_index_.fetch_add(1);
- if (entry_index < num_entries_) {
- entries_[entry_index] = entry;
+ std::lock_guard<std::mutex> entries_lock(entries_lock_);
+ if (cur_index_ == entries_.size()) {
+ // Maxed out, throw the entry away.
+ return;
+ }
+
+ entries_[cur_index_++].reset(entry);
+ if (cur_index_ == entries_.size()) {
+ info_log("Maximum number of records added, all new operations will be dropped.");
}
}
@@ -215,9 +197,4 @@
}
AddEntryOnly(entry);
-
- // Check to see if it's time to dump the entries.
- if (dump_) {
- Dump();
- }
}
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index 3d37529..43dba6a 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -29,12 +29,15 @@
#pragma once
#include <pthread.h>
+#include <signal.h>
#include <stdint.h>
#include <unistd.h>
#include <atomic>
+#include <memory>
#include <mutex>
#include <string>
+#include <vector>
#include <platform/bionic/macros.h>
@@ -43,7 +46,7 @@
RecordEntry();
virtual ~RecordEntry() = default;
- virtual std::string GetString() const = 0;
+ virtual bool Write(int fd) const = 0;
protected:
pid_t tid_;
@@ -57,7 +60,7 @@
ThreadCompleteEntry() = default;
virtual ~ThreadCompleteEntry() = default;
- std::string GetString() const override;
+ bool Write(int fd) const override;
private:
BIONIC_DISALLOW_COPY_AND_ASSIGN(ThreadCompleteEntry);
@@ -80,7 +83,7 @@
MallocEntry(void* pointer, size_t size);
virtual ~MallocEntry() = default;
- std::string GetString() const override;
+ bool Write(int fd) const override;
protected:
size_t size_;
@@ -94,7 +97,7 @@
explicit FreeEntry(void* pointer);
virtual ~FreeEntry() = default;
- std::string GetString() const override;
+ bool Write(int fd) const override;
private:
BIONIC_DISALLOW_COPY_AND_ASSIGN(FreeEntry);
@@ -105,7 +108,7 @@
CallocEntry(void* pointer, size_t size, size_t nmemb);
virtual ~CallocEntry() = default;
- std::string GetString() const override;
+ bool Write(int fd) const override;
protected:
size_t nmemb_;
@@ -119,7 +122,7 @@
ReallocEntry(void* pointer, size_t size, void* old_pointer);
virtual ~ReallocEntry() = default;
- std::string GetString() const override;
+ bool Write(int fd) const override;
protected:
void* old_pointer_;
@@ -134,7 +137,7 @@
MemalignEntry(void* pointer, size_t size, size_t alignment);
virtual ~MemalignEntry() = default;
- std::string GetString() const override;
+ bool Write(int fd) const override;
protected:
size_t alignment_;
@@ -155,19 +158,18 @@
void AddEntry(const RecordEntry* entry);
void AddEntryOnly(const RecordEntry* entry);
- void SetToDump() { dump_ = true; }
-
pthread_key_t key() { return key_; }
private:
- void Dump();
+ static void WriteData(int, siginfo_t*, void*);
+ static RecordData* record_obj_;
- std::mutex dump_lock_;
+ void WriteEntries();
+
+ std::mutex entries_lock_;
pthread_key_t key_;
- const RecordEntry** entries_ = nullptr;
- size_t num_entries_ = 0;
- std::atomic_uint cur_index_;
- std::atomic_bool dump_;
+ std::vector<std::unique_ptr<const RecordEntry>> entries_;
+ size_t cur_index_;
std::string dump_file_;
BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordData);
diff --git a/libc/malloc_debug/Unreachable.cpp b/libc/malloc_debug/Unreachable.cpp
new file mode 100644
index 0000000..af47257
--- /dev/null
+++ b/libc/malloc_debug/Unreachable.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <atomic>
+#include <string>
+
+#include <memunreachable/memunreachable.h>
+#include <platform/bionic/macros.h>
+
+#include "Config.h"
+#include "Unreachable.h"
+#include "debug_log.h"
+
+std::atomic_bool Unreachable::do_check_;
+
+static void EnableUnreachableCheck(int, struct siginfo*, void*) {
+ Unreachable::EnableCheck();
+}
+
+void Unreachable::CheckIfRequested(const Config& config) {
+ if ((config.options() & CHECK_UNREACHABLE_ON_SIGNAL) && do_check_.exchange(false)) {
+ info_log("Starting to check for unreachable memory.");
+ if (!LogUnreachableMemory(false, 100)) {
+ error_log("Unreachable check failed, run setenforce 0 and try again.");
+ }
+ }
+}
+
+bool Unreachable::Initialize(const Config& config) {
+ if (!(config.options() & CHECK_UNREACHABLE_ON_SIGNAL)) {
+ return true;
+ }
+
+ struct sigaction64 unreachable_act = {};
+ unreachable_act.sa_sigaction = EnableUnreachableCheck;
+ unreachable_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
+ if (sigaction64(config.check_unreachable_signal(), &unreachable_act, nullptr) != 0) {
+ error_log("Unable to set up check unreachable signal function: %s", strerror(errno));
+ return false;
+ }
+
+ if (config.options() & VERBOSE) {
+ info_log("%s: Run: 'kill -%d %d' to check for unreachable memory.", getprogname(),
+ config.check_unreachable_signal(), getpid());
+ }
+
+ return true;
+}
diff --git a/libc/malloc_debug/Unreachable.h b/libc/malloc_debug/Unreachable.h
new file mode 100644
index 0000000..36c0bdb
--- /dev/null
+++ b/libc/malloc_debug/Unreachable.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <atomic>
+
+// Forward declarations
+class ConfigData;
+
+class Unreachable {
+ public:
+ static bool Initialize(const Config& config);
+ static void CheckIfRequested(const Config& config);
+
+ static void EnableCheck() { do_check_ = true; }
+
+ private:
+ static std::atomic_bool do_check_;
+
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(Unreachable);
+};
diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp
index f6c3e69..c892a39 100644
--- a/libc/malloc_debug/UnwindBacktrace.cpp
+++ b/libc/malloc_debug/UnwindBacktrace.cpp
@@ -36,11 +36,7 @@
#include <vector>
#include <android-base/stringprintf.h>
-#include <unwindstack/MapInfo.h>
-#include <unwindstack/Maps.h>
-#include <unwindstack/Memory.h>
-#include <unwindstack/Regs.h>
-#include <unwindstack/RegsGetLocal.h>
+#include <unwindstack/AndroidUnwinder.h>
#include <unwindstack/Unwinder.h>
#include "UnwindBacktrace.h"
@@ -54,51 +50,22 @@
extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
-static pthread_once_t g_setup_once = PTHREAD_ONCE_INIT;
-
-static unwindstack::LocalUpdatableMaps* g_maps;
-static std::shared_ptr<unwindstack::Memory> g_process_memory;
-#if defined(__LP64__)
-static std::vector<std::string> g_skip_libraries{"/system/lib64/libunwindstack.so",
- "/system/lib64/libc_malloc_debug.so"};
-#else
-static std::vector<std::string> g_skip_libraries{"/system/lib/libunwindstack.so",
- "/system/lib/libc_malloc_debug.so"};
-#endif
-
-static void Setup() {
- g_maps = new unwindstack::LocalUpdatableMaps;
- if (!g_maps->Parse()) {
- delete g_maps;
- g_maps = nullptr;
- }
-
- g_process_memory = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
-}
-
bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* frame_info,
size_t max_frames) {
- pthread_once(&g_setup_once, Setup);
-
- if (g_maps == nullptr) {
- return false;
- }
-
- std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
- unwindstack::RegsGetLocal(regs.get());
- unwindstack::Unwinder unwinder(max_frames, g_maps, regs.get(), g_process_memory);
- unwinder.Unwind(&g_skip_libraries);
- if (unwinder.NumFrames() == 0) {
+ [[clang::no_destroy]] static unwindstack::AndroidLocalUnwinder unwinder(
+ std::vector<std::string>{"libc_malloc_debug.so"});
+ unwindstack::AndroidUnwinderData data(max_frames);
+ if (!unwinder.Unwind(data)) {
frames->clear();
frame_info->clear();
return false;
}
- *frame_info = unwinder.ConsumeFrames();
- frames->resize(frame_info->size());
- for (size_t i = 0; i < frame_info->size(); i++) {
- frames->at(i) = frame_info->at(i).pc;
+ frames->resize(data.frames.size());
+ for (const auto& frame : data.frames) {
+ frames->at(frame.num) = frame.pc;
}
+ *frame_info = std::move(data.frames);
return true;
}
diff --git a/libc/malloc_debug/UnwindBacktrace.h b/libc/malloc_debug/UnwindBacktrace.h
index 7f89907..091865e 100644
--- a/libc/malloc_debug/UnwindBacktrace.h
+++ b/libc/malloc_debug/UnwindBacktrace.h
@@ -30,10 +30,8 @@
#include <stdint.h>
-#include <string>
#include <vector>
-#include <unwindstack/MapInfo.h>
#include <unwindstack/Unwinder.h>
bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* info,
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 9f38946..617858a 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -53,11 +53,12 @@
#include "Config.h"
#include "DebugData.h"
+#include "Unreachable.h"
+#include "UnwindBacktrace.h"
#include "backtrace.h"
#include "debug_disable.h"
#include "debug_log.h"
#include "malloc_debug.h"
-#include "UnwindBacktrace.h"
// ------------------------------------------------------------------------
// Global Data
@@ -315,7 +316,7 @@
}
DebugData* debug = new DebugData();
- if (!debug->Initialize(options)) {
+ if (!debug->Initialize(options) || !Unreachable::Initialize(debug->config())) {
delete debug;
DebugDisableFinalize();
return false;
@@ -402,6 +403,8 @@
}
size_t debug_malloc_usable_size(void* pointer) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled() || pointer == nullptr) {
return g_dispatch->malloc_usable_size(pointer);
}
@@ -467,6 +470,8 @@
}
void* debug_malloc(size_t size) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled()) {
return g_dispatch->malloc(size);
}
@@ -517,8 +522,8 @@
if (g_debug->config().options() & FILL_ON_FREE) {
size_t fill_bytes = g_debug->config().fill_on_free_bytes();
- bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
- memset(pointer, g_debug->config().fill_free_value(), bytes);
+ fill_bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
+ memset(pointer, g_debug->config().fill_free_value(), fill_bytes);
}
if (g_debug->TrackPointers()) {
@@ -531,7 +536,7 @@
// frees at the same time and we wind up trying to really free this
// pointer from another thread, while still trying to free it in
// this function.
- pointer = PointerData::AddFreed(pointer);
+ pointer = PointerData::AddFreed(pointer, bytes);
if (pointer != nullptr) {
if (g_debug->HeaderEnabled()) {
pointer = g_debug->GetHeader(pointer)->orig_pointer;
@@ -544,6 +549,8 @@
}
void debug_free(void* pointer) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled() || pointer == nullptr) {
return g_dispatch->free(pointer);
}
@@ -563,6 +570,8 @@
}
void* debug_memalign(size_t alignment, size_t bytes) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled()) {
return g_dispatch->memalign(alignment, bytes);
}
@@ -643,6 +652,8 @@
}
void* debug_realloc(void* pointer, size_t bytes) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled()) {
return g_dispatch->realloc(pointer, bytes);
}
@@ -763,6 +774,8 @@
}
void* debug_calloc(size_t nmemb, size_t bytes) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled()) {
return g_dispatch->calloc(nmemb, bytes);
}
@@ -862,6 +875,8 @@
}
void* debug_aligned_alloc(size_t alignment, size_t size) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled()) {
return g_dispatch->aligned_alloc(alignment, size);
}
@@ -873,6 +888,8 @@
}
int debug_posix_memalign(void** memptr, size_t alignment, size_t size) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled()) {
return g_dispatch->posix_memalign(memptr, alignment, size);
}
@@ -890,10 +907,9 @@
void* arg) {
ScopedConcurrentLock lock;
if (g_debug->TrackPointers()) {
- // Since malloc is disabled, don't bother acquiring any locks.
- for (auto it = PointerData::begin(); it != PointerData::end(); ++it) {
- callback(it->first, InternalMallocUsableSize(reinterpret_cast<void*>(it->first)), arg);
- }
+ PointerData::IteratePointers([&callback, &arg](uintptr_t pointer) {
+ callback(pointer, InternalMallocUsableSize(reinterpret_cast<void*>(pointer)), arg);
+ });
return 0;
}
@@ -935,6 +951,8 @@
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
void* debug_pvalloc(size_t bytes) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled()) {
return g_dispatch->pvalloc(bytes);
}
@@ -950,6 +968,8 @@
}
void* debug_valloc(size_t size) {
+ Unreachable::CheckIfRequested(g_debug->config());
+
if (DebugCallsDisabled()) {
return g_dispatch->valloc(size);
}
diff --git a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
index 42d1415..0a0eaef 100644
--- a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
@@ -761,3 +761,87 @@
"which does not take a value\n");
ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
}
+
+TEST_F(MallocDebugConfigTest, check_unreachable_on_signal) {
+ ASSERT_TRUE(InitConfig("check_unreachable_on_signal")) << getFakeLogPrint();
+ ASSERT_EQ(CHECK_UNREACHABLE_ON_SIGNAL, config->options());
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, trigger_check_unreachable_on_signal_fail) {
+ ASSERT_FALSE(InitConfig("check_unreachable_on_signal=200")) << getFakeLogPrint();
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string log_msg(
+ "6 malloc_debug malloc_testing: value set for option 'check_unreachable_on_signal' "
+ "which does not take a value\n");
+ ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, size) {
+ ASSERT_TRUE(InitConfig("backtrace_size=37")) << getFakeLogPrint();
+ ASSERT_EQ(BACKTRACE_SPECIFIC_SIZES, config->options());
+ ASSERT_EQ(37U, config->backtrace_min_size_bytes());
+ ASSERT_EQ(37U, config->backtrace_max_size_bytes());
+
+ ASSERT_FALSE(InitConfig("backtrace_size")) << getFakeLogPrint();
+ ASSERT_FALSE(InitConfig("backtrace_size=0")) << getFakeLogPrint();
+ ASSERT_FALSE(InitConfig("backtrace_size=-1")) << getFakeLogPrint();
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string log_msg("6 malloc_debug malloc_testing: bad value for option 'backtrace_size'\n" +
+ usage_string +
+ "6 malloc_debug malloc_testing: bad value for option 'backtrace_size', value "
+ "must be >= 1: 0\n" +
+ usage_string +
+ "6 malloc_debug malloc_testing: bad value for option 'backtrace_size', value "
+ "cannot be negative: -1\n" +
+ usage_string);
+ ASSERT_STREQ(log_msg.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, min_size) {
+ ASSERT_TRUE(InitConfig("backtrace_min_size=9")) << getFakeLogPrint();
+ ASSERT_EQ(BACKTRACE_SPECIFIC_SIZES, config->options());
+ ASSERT_EQ(9U, config->backtrace_min_size_bytes());
+ ASSERT_EQ(SIZE_MAX, config->backtrace_max_size_bytes());
+
+ ASSERT_FALSE(InitConfig("backtrace_min_size")) << getFakeLogPrint();
+ ASSERT_FALSE(InitConfig("backtrace_min_size=0")) << getFakeLogPrint();
+ ASSERT_FALSE(InitConfig("backtrace_min_size=-1")) << getFakeLogPrint();
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string log_msg("6 malloc_debug malloc_testing: bad value for option 'backtrace_min_size'\n" +
+ usage_string +
+ "6 malloc_debug malloc_testing: bad value for option 'backtrace_min_size', "
+ "value must be >= 1: 0\n" +
+ usage_string +
+ "6 malloc_debug malloc_testing: bad value for option 'backtrace_min_size', "
+ "value cannot be negative: -1\n" +
+ usage_string);
+ ASSERT_STREQ(log_msg.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, max_size) {
+ ASSERT_TRUE(InitConfig("backtrace_max_size=13")) << getFakeLogPrint();
+ ASSERT_EQ(BACKTRACE_SPECIFIC_SIZES, config->options());
+ ASSERT_EQ(0U, config->backtrace_min_size_bytes());
+ ASSERT_EQ(13U, config->backtrace_max_size_bytes());
+
+ ASSERT_FALSE(InitConfig("backtrace_max_size")) << getFakeLogPrint();
+ ASSERT_FALSE(InitConfig("backtrace_max_size=0")) << getFakeLogPrint();
+ ASSERT_FALSE(InitConfig("backtrace_max_size=-1")) << getFakeLogPrint();
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string log_msg("6 malloc_debug malloc_testing: bad value for option 'backtrace_max_size'\n" +
+ usage_string +
+ "6 malloc_debug malloc_testing: bad value for option 'backtrace_max_size', "
+ "value must be >= 1: 0\n" +
+ usage_string +
+ "6 malloc_debug malloc_testing: bad value for option 'backtrace_max_size', "
+ "value cannot be negative: -1\n" +
+ usage_string);
+ ASSERT_STREQ(log_msg.c_str(), getFakeLogPrint().c_str());
+}
diff --git a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
index 92679e4..aee2572 100644
--- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
@@ -52,8 +52,7 @@
#include <thread>
#include <vector>
-#include <backtrace/Backtrace.h>
-#include <backtrace/BacktraceMap.h>
+#include <unwindstack/AndroidUnwinder.h>
#include <bionic/malloc.h>
#include <tests/utils.h>
@@ -452,12 +451,19 @@
static constexpr size_t kMaxRetries = 3;
};
-TEST(MallocTests, DISABLED_smoke) {}
+TEST(MallocTests, DISABLED_smoke) {
+ void* ptr = malloc(128);
+ free(ptr);
+}
TEST_F(MallocDebugSystemTest, smoke) {
Exec("MallocTests.DISABLED_smoke", "verbose backtrace");
}
+TEST_F(MallocDebugSystemTest, backtrace_full_smoke) {
+ Exec("MallocTests.DISABLED_smoke", "verbose backtrace backtrace_full");
+}
+
static void SetAllocationLimit() {
// Set to a large value, this is only to enable the limit code and
// verify that malloc debug is still called properly.
@@ -763,13 +769,14 @@
}
static constexpr size_t kNumUnwinds = 1000;
+ unwindstack::AndroidLocalUnwinder unwinder;
for (size_t i = 0; i < kNumUnwinds; i++) {
- std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), tid));
// Only verify that there is at least one frame in the unwind.
// This is not a test of the unwinder and clang for arm seems to
// produces an increasing number of code that does not have unwind
// information.
- ASSERT_TRUE(backtrace->Unwind(0)) << "Failed on unwind " << i;
+ unwindstack::AndroidUnwinderData data;
+ ASSERT_TRUE(unwinder.Unwind(data)) << "Failed on unwind " << i;
}
running = false;
thread.join();
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index ea2dc78..c6378f5 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -81,8 +81,19 @@
bool debug_write_malloc_leak_info(FILE*);
void debug_dump_heap(const char*);
+void malloc_enable();
+void malloc_disable();
+
__END_DECLS
+// Change the slow threshold since some tests take more than 2 seconds.
+extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) {
+ static const char* initial_args[] = {"--slow_threshold_ms=5000"};
+ *args = initial_args;
+ *num_args = 1;
+ return true;
+}
+
constexpr char DIVIDER[] =
"6 malloc_debug *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n";
@@ -90,7 +101,7 @@
return __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
}
-static constexpr const char RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs.txt";
+static constexpr const char RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs";
static constexpr const char BACKTRACE_DUMP_PREFIX[] = "/data/local/tmp/backtrace_heap";
@@ -100,14 +111,16 @@
initialized = false;
resetLogs();
backtrace_fake_clear_all();
- // Delete the record data file if it exists.
- unlink(RECORD_ALLOCS_FILE);
}
void TearDown() override {
if (initialized) {
debug_finalize();
}
+ if (!record_filename.empty()) {
+ // Try to delete the record data file even it doesn't exist.
+ unlink(record_filename.c_str());
+ }
}
void Init(const char* options) {
@@ -116,6 +129,13 @@
initialized = true;
}
+ void InitRecordAllocs(const char* options) {
+ record_filename = android::base::StringPrintf("%s.%d.txt", RECORD_ALLOCS_FILE, getpid());
+ std::string init(options);
+ init += android::base::StringPrintf(" record_allocs_file=%s", record_filename.c_str());
+ Init(init.c_str());
+ }
+
void BacktraceDumpOnSignal(bool trigger_with_alloc);
static size_t GetInfoEntrySize(size_t max_frames) {
@@ -126,6 +146,8 @@
bool zygote_child;
+ std::string record_filename;
+
static MallocDispatch dispatch;
};
@@ -227,6 +249,9 @@
expected_log += android::base::StringPrintf(
"4 malloc_debug malloc_testing: Run: 'kill -%d %d' to dump the allocation records.\n",
SIGRTMAX - 18, getpid());
+ expected_log += android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to check for unreachable memory.\n",
+ SIGRTMAX - 16, getpid());
}
expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
@@ -296,6 +321,16 @@
ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugTest, verbose_check_unreachable_on_signal) {
+ Init("verbose check_unreachable_on_signal");
+
+ std::string expected_log = android::base::StringPrintf(
+ "4 malloc_debug malloc_testing: Run: 'kill -%d %d' to check for unreachable memory.\n",
+ SIGRTMAX - 16, getpid());
+ expected_log += "4 malloc_debug malloc_testing: malloc debug enabled\n";
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
TEST_F(MallocDebugTest, fill_on_free) {
Init("fill_on_free free_track free_track_backtrace_num_frames=0");
@@ -359,7 +394,7 @@
TEST_F(MallocDebugTest, all_options) {
Init(
"guard backtrace backtrace_enable_on_signal fill expand_alloc free_track leak_track "
- "record_allocs verify_pointers abort_on_error verbose");
+ "record_allocs verify_pointers abort_on_error verbose check_unreachable_on_signal");
VerifyAllocCalls(true);
}
@@ -2135,7 +2170,7 @@
}
#endif
-void VerifyRecordAllocs() {
+void VerifyRecordAllocs(const std::string& record_filename) {
std::string expected;
void* pointer = debug_malloc(10);
@@ -2195,40 +2230,31 @@
// Dump all of the data accumulated so far.
ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
- sleep(1);
-
- // This triggers the dumping.
- pointer = debug_malloc(110);
- ASSERT_TRUE(pointer != nullptr);
- expected += android::base::StringPrintf("%d: malloc %p 110\n", getpid(), pointer);
// Read all of the contents.
std::string actual;
- ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
- ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+ ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
ASSERT_STREQ(expected.c_str(), actual.c_str());
ASSERT_STREQ("", getFakeLogBuf().c_str());
ASSERT_STREQ("", getFakeLogPrint().c_str());
-
- debug_free(pointer);
}
TEST_F(MallocDebugTest, record_allocs_no_header) {
- Init("record_allocs");
+ InitRecordAllocs("record_allocs");
- VerifyRecordAllocs();
+ VerifyRecordAllocs(record_filename);
}
TEST_F(MallocDebugTest, record_allocs_with_header) {
- Init("record_allocs front_guard");
+ InitRecordAllocs("record_allocs front_guard");
- VerifyRecordAllocs();
+ VerifyRecordAllocs(record_filename);
}
TEST_F(MallocDebugTest, record_allocs_max) {
- Init("record_allocs=5");
+ InitRecordAllocs("record_allocs=5");
std::string expected;
@@ -2251,27 +2277,21 @@
// Dump all of the data accumulated so far.
ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
- sleep(1);
-
- // This triggers the dumping.
- pointer = debug_malloc(110);
- ASSERT_TRUE(pointer != nullptr);
// Read all of the contents.
std::string actual;
- ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
- ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+ ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
ASSERT_STREQ(expected.c_str(), actual.c_str());
ASSERT_STREQ("", getFakeLogBuf().c_str());
- ASSERT_STREQ("", getFakeLogPrint().c_str());
-
- debug_free(pointer);
+ ASSERT_STREQ(
+ "4 malloc_debug Maximum number of records added, all new operations will be dropped.\n",
+ getFakeLogPrint().c_str());
}
TEST_F(MallocDebugTest, record_allocs_thread_done) {
- Init("record_allocs=5");
+ InitRecordAllocs("record_allocs=5");
static pid_t tid = 0;
static void* pointer = nullptr;
@@ -2289,34 +2309,25 @@
// Dump all of the data accumulated so far.
ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
- sleep(1);
-
- // This triggers the dumping.
- pointer = debug_malloc(23);
- ASSERT_TRUE(pointer != nullptr);
- expected += android::base::StringPrintf("%d: malloc %p 23\n", getpid(), pointer);
// Read all of the contents.
std::string actual;
- ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
- ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+ ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
ASSERT_STREQ(expected.c_str(), actual.c_str());
ASSERT_STREQ("", getFakeLogBuf().c_str());
ASSERT_STREQ("", getFakeLogPrint().c_str());
-
- debug_free(pointer);
}
TEST_F(MallocDebugTest, record_allocs_file_name_fail) {
- Init("record_allocs=5");
+ InitRecordAllocs("record_allocs=5");
- // Delete the special.txt file and create a symbolic link there to
+ // Delete the records file and create a symbolic link there to
// make sure the create file will fail.
- unlink(RECORD_ALLOCS_FILE);
+ unlink(record_filename.c_str());
- ASSERT_EQ(0, symlink("/data/local/tmp/does_not_exist", RECORD_ALLOCS_FILE));
+ ASSERT_EQ(0, symlink("/data/local/tmp/does_not_exist", record_filename.c_str()));
std::string expected;
@@ -2328,39 +2339,62 @@
// Dump all of the data accumulated so far.
ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
- sleep(1);
-
- // This triggers the dumping.
- pointer = debug_malloc(110);
- ASSERT_TRUE(pointer != nullptr);
- expected += android::base::StringPrintf("%d: malloc %p 110\n", getpid(), pointer);
// Read all of the contents.
std::string actual;
- ASSERT_FALSE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
+ ASSERT_FALSE(android::base::ReadFileToString(record_filename, &actual));
// Unlink the file so the next dump passes.
- ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+ ASSERT_EQ(0, unlink(record_filename.c_str()));
// Dump all of the data accumulated so far.
ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
- sleep(1);
- // This triggers the dumping.
- debug_free(pointer);
- expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
-
- ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
- ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+ ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
ASSERT_STREQ(expected.c_str(), actual.c_str());
ASSERT_STREQ("", getFakeLogBuf().c_str());
std::string expected_log = android::base::StringPrintf(
"6 malloc_debug Cannot create record alloc file %s: Too many symbolic links encountered\n",
- RECORD_ALLOCS_FILE);
+ record_filename.c_str());
ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugTest, record_allocs_no_entries_to_write) {
+ InitRecordAllocs("record_allocs=5");
+
+ kill(getpid(), SIGRTMAX - 18);
+
+ std::string actual;
+ ASSERT_FALSE(android::base::ReadFileToString(record_filename, &actual));
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("4 malloc_debug No alloc entries to write.\n", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, record_allocs_write_entries_does_not_allocate) {
+ InitRecordAllocs("record_allocs=5");
+
+ std::string expected;
+
+ void* pointer = debug_malloc(10);
+ ASSERT_TRUE(pointer != nullptr);
+ expected += android::base::StringPrintf("%d: malloc %p 10\n", getpid(), pointer);
+ debug_free(pointer);
+ expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
+
+ malloc_disable();
+ kill(getpid(), SIGRTMAX - 18);
+ malloc_enable();
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
TEST_F(MallocDebugTest, verify_pointers) {
Init("verify_pointers");
@@ -2695,3 +2729,209 @@
std::string expected_log = std::string("6 malloc_debug Dumping to file: ") + tf.path + "\n\n";
ASSERT_EQ(expected_log, getFakeLogPrint());
}
+
+extern "C" bool LogUnreachableMemory(bool, size_t) {
+ static bool return_value = false;
+ return_value = !return_value;
+ return return_value;
+}
+
+TEST_F(MallocDebugTest, check_unreachable_on_signal) {
+ Init("check_unreachable_on_signal");
+
+ ASSERT_TRUE(kill(getpid(), SIGRTMAX - 16) == 0);
+ sleep(1);
+
+ // The first unreachable check will pass.
+ void* pointer = debug_malloc(110);
+ ASSERT_TRUE(pointer != nullptr);
+
+ ASSERT_TRUE(kill(getpid(), SIGRTMAX - 16) == 0);
+ sleep(1);
+
+ // The second unreachable check will fail.
+ debug_free(pointer);
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string expected_log = "4 malloc_debug Starting to check for unreachable memory.\n";
+ ASSERT_STREQ(
+ "4 malloc_debug Starting to check for unreachable memory.\n"
+ "4 malloc_debug Starting to check for unreachable memory.\n"
+ "6 malloc_debug Unreachable check failed, run setenforce 0 and try again.\n",
+ getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_size) {
+ Init("leak_track backtrace backtrace_size=120");
+
+ backtrace_fake_add(std::vector<uintptr_t>{0x1000, 0x2000, 0x3000});
+
+ void* pointer1 = debug_malloc(119);
+ ASSERT_TRUE(pointer1 != nullptr);
+
+ backtrace_fake_add(std::vector<uintptr_t>{0xa000, 0xb000, 0xc000, 0xd000});
+
+ void* pointer2 = debug_malloc(120);
+ ASSERT_TRUE(pointer2 != nullptr);
+
+ backtrace_fake_add(std::vector<uintptr_t>{0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
+
+ void* pointer3 = debug_malloc(121);
+ ASSERT_TRUE(pointer3 != nullptr);
+
+ debug_finalize();
+ initialized = false;
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string expected_log = android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 121 at %p (leak 1 of 3)\n", pointer3);
+
+ expected_log += android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 120 at %p (leak 2 of 3)\n", pointer2);
+ expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
+ expected_log += "6 malloc_debug #00 pc 0x1000\n";
+ expected_log += "6 malloc_debug #01 pc 0x2000\n";
+ expected_log += "6 malloc_debug #02 pc 0x3000\n";
+
+ expected_log += android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 119 at %p (leak 3 of 3)\n", pointer1);
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_min_size) {
+ Init("leak_track backtrace backtrace_min_size=1000");
+
+ backtrace_fake_add(std::vector<uintptr_t>{0x1000, 0x2000, 0x3000});
+
+ void* pointer1 = debug_malloc(500);
+ ASSERT_TRUE(pointer1 != nullptr);
+
+ backtrace_fake_add(std::vector<uintptr_t>{0xa000, 0xb000, 0xc000, 0xd000});
+
+ void* pointer2 = debug_malloc(1000);
+ ASSERT_TRUE(pointer2 != nullptr);
+
+ backtrace_fake_add(std::vector<uintptr_t>{0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
+
+ void* pointer3 = debug_malloc(1001);
+ ASSERT_TRUE(pointer3 != nullptr);
+
+ debug_finalize();
+ initialized = false;
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string expected_log = android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 1001 at %p (leak 1 of 3)\n",
+ pointer3);
+ expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
+ expected_log += "6 malloc_debug #00 pc 0xa000\n";
+ expected_log += "6 malloc_debug #01 pc 0xb000\n";
+ expected_log += "6 malloc_debug #02 pc 0xc000\n";
+ expected_log += "6 malloc_debug #03 pc 0xd000\n";
+
+ expected_log += android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 1000 at %p (leak 2 of 3)\n",
+ pointer2);
+ expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
+ expected_log += "6 malloc_debug #00 pc 0x1000\n";
+ expected_log += "6 malloc_debug #01 pc 0x2000\n";
+ expected_log += "6 malloc_debug #02 pc 0x3000\n";
+
+ expected_log += android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 500 at %p (leak 3 of 3)\n", pointer1);
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_max_size) {
+ Init("leak_track backtrace backtrace_max_size=1000");
+
+ backtrace_fake_add(std::vector<uintptr_t>{0x1000, 0x2000, 0x3000});
+
+ void* pointer1 = debug_malloc(1000);
+ ASSERT_TRUE(pointer1 != nullptr);
+
+ backtrace_fake_add(std::vector<uintptr_t>{0xa000, 0xb000, 0xc000, 0xd000});
+
+ void* pointer2 = debug_malloc(1001);
+ ASSERT_TRUE(pointer2 != nullptr);
+
+ backtrace_fake_add(std::vector<uintptr_t>{0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
+
+ void* pointer3 = debug_malloc(5000);
+ ASSERT_TRUE(pointer3 != nullptr);
+
+ debug_finalize();
+ initialized = false;
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string expected_log = android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 5000 at %p (leak 1 of 3)\n",
+ pointer3);
+
+ expected_log += android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 1001 at %p (leak 2 of 3)\n",
+ pointer2);
+
+ expected_log += android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 1000 at %p (leak 3 of 3)\n",
+ pointer1);
+ expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
+ expected_log += "6 malloc_debug #00 pc 0x1000\n";
+ expected_log += "6 malloc_debug #01 pc 0x2000\n";
+ expected_log += "6 malloc_debug #02 pc 0x3000\n";
+
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, backtrace_only_some_sizes_with_backtrace_min_max_size) {
+ Init("leak_track backtrace backtrace_min_size=50 backtrace_max_size=1000");
+
+ backtrace_fake_add(std::vector<uintptr_t>{0x1000, 0x2000, 0x3000});
+
+ void* pointer1 = debug_malloc(49);
+ ASSERT_TRUE(pointer1 != nullptr);
+
+ backtrace_fake_add(std::vector<uintptr_t>{0xa000, 0xb000, 0xc000, 0xd000});
+
+ void* pointer2 = debug_malloc(50);
+ ASSERT_TRUE(pointer2 != nullptr);
+
+ backtrace_fake_add(std::vector<uintptr_t>{0xfe000, 0xde000, 0xce000, 0xbe000, 0xae000});
+
+ void* pointer3 = debug_malloc(1000);
+ ASSERT_TRUE(pointer3 != nullptr);
+
+ backtrace_fake_add(std::vector<uintptr_t>{0x1a000, 0x1b000, 0x1c000, 0x1d000, 0x1e000});
+
+ void* pointer4 = debug_malloc(1001);
+ ASSERT_TRUE(pointer4 != nullptr);
+
+ debug_finalize();
+ initialized = false;
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string expected_log = android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 1001 at %p (leak 1 of 4)\n",
+ pointer4);
+
+ expected_log += android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 1000 at %p (leak 2 of 4)\n",
+ pointer3);
+ expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
+ expected_log += "6 malloc_debug #00 pc 0xa000\n";
+ expected_log += "6 malloc_debug #01 pc 0xb000\n";
+ expected_log += "6 malloc_debug #02 pc 0xc000\n";
+ expected_log += "6 malloc_debug #03 pc 0xd000\n";
+
+ expected_log += android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 50 at %p (leak 3 of 4)\n", pointer2);
+ expected_log += "6 malloc_debug Backtrace at time of allocation:\n";
+ expected_log += "6 malloc_debug #00 pc 0x1000\n";
+ expected_log += "6 malloc_debug #01 pc 0x2000\n";
+ expected_log += "6 malloc_debug #02 pc 0x3000\n";
+
+ expected_log += android::base::StringPrintf(
+ "6 malloc_debug +++ malloc_testing leaked block of size 49 at %p (leak 4 of 4)\n", pointer1);
+
+ ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
+}
diff --git a/libc/platform/bionic/macros.h b/libc/platform/bionic/macros.h
index 076cff1..9e13e0d 100644
--- a/libc/platform/bionic/macros.h
+++ b/libc/platform/bionic/macros.h
@@ -55,6 +55,8 @@
#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined x30")
#elif defined(__i386__)
#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined \%eip")
+#elif defined(__riscv)
+#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined ra")
#elif defined(__x86_64__)
#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined \%rip")
#endif
diff --git a/libc/platform/bionic/malloc.h b/libc/platform/bionic/malloc.h
index f0f13d0..ecc8743 100644
--- a/libc/platform/bionic/malloc.h
+++ b/libc/platform/bionic/malloc.h
@@ -100,6 +100,9 @@
// arg_size = sizeof(android_mallopt_gwp_asan_options_t)
M_INITIALIZE_GWP_ASAN = 10,
#define M_INITIALIZE_GWP_ASAN M_INITIALIZE_GWP_ASAN
+ // Query whether memtag stack is enabled for this process.
+ M_MEMTAG_STACK_IS_ON = 11,
+#define M_MEMTAG_STACK_IS_ON M_MEMTAG_STACK_IS_ON
};
typedef struct {
@@ -133,7 +136,7 @@
} android_mallopt_gwp_asan_options_t;
// Manipulates bionic-specific handling of memory allocation APIs such as
-// malloc. Only for use by the Android platform itself.
+// malloc. Only for use by the Android platform and APEXes.
//
// On success, returns true. On failure, returns false and sets errno.
extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size);
diff --git a/libc/platform/bionic/tls.h b/libc/platform/bionic/tls.h
index bf9e65b..e01eccd 100644
--- a/libc/platform/bionic/tls.h
+++ b/libc/platform/bionic/tls.h
@@ -34,6 +34,8 @@
# define __get_tls() ({ void** __val; __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__val)); __val; })
#elif defined(__i386__)
# define __get_tls() ({ void** __val; __asm__("movl %%gs:0, %0" : "=r"(__val)); __val; })
+#elif defined(__riscv)
+# define __get_tls() ({ void** __val; __asm__("mv %0, tp" : "=r"(__val)); __val; })
#elif defined(__x86_64__)
# define __get_tls() ({ void** __val; __asm__("mov %%fs:0, %0" : "=r"(__val)); __val; })
#else
diff --git a/libc/platform/bionic/tls_defines.h b/libc/platform/bionic/tls_defines.h
index 78099b3..3e2efa3 100644
--- a/libc/platform/bionic/tls_defines.h
+++ b/libc/platform/bionic/tls_defines.h
@@ -114,6 +114,28 @@
#define TLS_SLOT_BIONIC_TLS 9
#define MAX_TLS_SLOT 9 // update this value when reserving a slot
+#elif defined(__riscv)
+
+// RISC-V ELF Specification[1] specifies that RISC-V uses Variant I as described
+// by the ELF TLS specification, with tp containing the address one past the end
+// of the TCB.
+//
+// [1]: RISC-V ELF Specification. Section: Thread Local Storage
+// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#thread-local-storage
+
+#define MIN_TLS_SLOT (-9) // update this value when reserving a slot
+
+#define TLS_SLOT_BIONIC_TLS (-9)
+#define TLS_SLOT_DTV (-8)
+#define TLS_SLOT_THREAD_ID (-7)
+#define TLS_SLOT_APP (-6)
+#define TLS_SLOT_OPENGL (-5)
+#define TLS_SLOT_OPENGL_API (-4)
+#define TLS_SLOT_STACK_GUARD (-3)
+#define TLS_SLOT_SANITIZER (-2)
+#define TLS_SLOT_ART_THREAD_SELF (-1)
+#define MAX_TLS_SLOT (-1)
+
#endif
#define BIONIC_TLS_SLOTS (MAX_TLS_SLOT - MIN_TLS_SLOT + 1)
diff --git a/libc/private/bionic_asm.h b/libc/private/bionic_asm.h
index d68a2d6..78e5046 100644
--- a/libc/private/bionic_asm.h
+++ b/libc/private/bionic_asm.h
@@ -45,6 +45,8 @@
#include <private/bionic_asm_arm.h>
#elif defined(__i386__)
#include <private/bionic_asm_x86.h>
+#elif defined(__riscv)
+#include <private/bionic_asm_riscv64.h>
#elif defined(__x86_64__)
#include <private/bionic_asm_x86_64.h>
#endif
diff --git a/libc/private/bionic_asm_arm64.h b/libc/private/bionic_asm_arm64.h
index 5d83d9b..ffc7181 100644
--- a/libc/private/bionic_asm_arm64.h
+++ b/libc/private/bionic_asm_arm64.h
@@ -76,3 +76,4 @@
#define NT_MEMTAG_LEVEL_ASYNC 1
#define NT_MEMTAG_LEVEL_SYNC 2
#define NT_MEMTAG_HEAP 4
+#define NT_MEMTAG_STACK 8
diff --git a/libc/private/bionic_asm_riscv64.h b/libc/private/bionic_asm_riscv64.h
new file mode 100644
index 0000000..463ca31
--- /dev/null
+++ b/libc/private/bionic_asm_riscv64.h
@@ -0,0 +1,43 @@
+/* $OpenBSD: asm.h,v 1.1 2004/02/01 05:09:49 drahn Exp $ */
+/* $NetBSD: asm.h,v 1.4 2001/07/16 05:43:32 matt Exp $ */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)asm.h 5.5 (Berkeley) 5/7/91
+ */
+
+#pragma once
+
+#define __bionic_asm_align 16
+
+#undef __bionic_asm_function_type
+#define __bionic_asm_function_type %function
diff --git a/libc/private/bionic_elf_tls.h b/libc/private/bionic_elf_tls.h
index e0ec7b5..79ffcc4 100644
--- a/libc/private/bionic_elf_tls.h
+++ b/libc/private/bionic_elf_tls.h
@@ -201,3 +201,18 @@
struct bionic_tcb;
void __free_dynamic_tls(bionic_tcb* tcb);
void __notify_thread_exit_callbacks();
+
+#if defined(__riscv)
+// TLS_DTV_OFFSET is a constant used in relocation fields, defined in RISC-V ELF Specification[1]
+// The front of the TCB contains a pointer to the DTV, and each pointer in DTV
+// points to 0x800 past the start of a TLS block to make full use of the range
+// of load/store instructions, refer to [2].
+//
+// [1]: RISC-V ELF Specification.
+// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#constants
+// [2]: Documentation of TLS data structures
+// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/53
+#define TLS_DTV_OFFSET 0x800
+#else
+#define TLS_DTV_OFFSET 0
+#endif
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index e105c18..c7e951d 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -29,24 +29,25 @@
#ifndef _PRIVATE_BIONIC_GLOBALS_H
#define _PRIVATE_BIONIC_GLOBALS_H
+#include <inttypes.h>
+#include <link.h>
+#include <platform/bionic/malloc.h>
+#include <pthread.h>
#include <stdatomic.h>
#include <sys/cdefs.h>
-#include <link.h>
-#include <pthread.h>
+#include "private/WriteProtected.h"
#include "private/bionic_allocator.h"
#include "private/bionic_elf_tls.h"
#include "private/bionic_fdsan.h"
#include "private/bionic_malloc_dispatch.h"
#include "private/bionic_vdso.h"
-#include "private/WriteProtected.h"
-
-#include <platform/bionic/malloc.h>
struct libc_globals {
vdso_entry vdso[VDSO_END];
long setjmp_cookie;
uintptr_t heap_pointer_tag;
+ _Atomic(bool) memtag_stack;
// In order to allow a complete switch between dispatch tables without
// the need for copying each function by function in the structure,
@@ -112,6 +113,8 @@
const char* scudo_ring_buffer = nullptr;
HeapTaggingLevel initial_heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE;
+ bool initial_memtag_stack = false;
+ int64_t heap_tagging_upgrade_timer_sec = 0;
};
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();
diff --git a/libc/seccomp/seccomp_bpfs.h b/libc/seccomp/seccomp_bpfs.h
index 3bdffa9..34219e2 100644
--- a/libc/seccomp/seccomp_bpfs.h
+++ b/libc/seccomp/seccomp_bpfs.h
@@ -33,6 +33,13 @@
extern const struct sock_filter arm64_system_filter[];
extern const size_t arm64_system_filter_size;
+extern const struct sock_filter riscv64_app_filter[];
+extern const size_t riscv64_app_filter_size;
+extern const struct sock_filter riscv64_app_zygote_filter[];
+extern const size_t riscv64_app_zygote_filter_size;
+extern const struct sock_filter riscv64_system_filter[];
+extern const size_t riscv64_system_filter_size;
+
extern const struct sock_filter x86_app_filter[];
extern const size_t x86_app_filter_size;
extern const struct sock_filter x86_app_zygote_filter[];
diff --git a/libc/seccomp/seccomp_policy.cpp b/libc/seccomp/seccomp_policy.cpp
index a42816e..1ca4eec 100644
--- a/libc/seccomp/seccomp_policy.cpp
+++ b/libc/seccomp/seccomp_policy.cpp
@@ -25,13 +25,13 @@
#include <vector>
#include <android-base/logging.h>
+#include <android-base/macros.h>
#include "func_to_syscall_nrs.h"
#include "seccomp_bpfs.h"
#if defined __arm__ || defined __aarch64__
-#define DUAL_ARCH
#define PRIMARY_ARCH AUDIT_ARCH_AARCH64
static const struct sock_filter* primary_app_filter = arm64_app_filter;
static const size_t primary_app_filter_size = arm64_app_filter_size;
@@ -52,9 +52,9 @@
static const long secondary_setresgid = __arm_setresgid;
static const long secondary_setresuid = __arm_setresuid;
+
#elif defined __i386__ || defined __x86_64__
-#define DUAL_ARCH
#define PRIMARY_ARCH AUDIT_ARCH_X86_64
static const struct sock_filter* primary_app_filter = x86_64_app_filter;
static const size_t primary_app_filter_size = x86_64_app_filter_size;
@@ -75,6 +75,20 @@
static const long secondary_setresgid = __x86_setresgid;
static const long secondary_setresuid = __x86_setresuid;
+
+#elif defined(__riscv)
+
+#define PRIMARY_ARCH AUDIT_ARCH_RISCV64
+static const struct sock_filter* primary_app_filter = riscv64_app_filter;
+static const size_t primary_app_filter_size = riscv64_app_filter_size;
+static const struct sock_filter* primary_app_zygote_filter = riscv64_app_zygote_filter;
+static const size_t primary_app_zygote_filter_size = riscv64_app_zygote_filter_size;
+static const struct sock_filter* primary_system_filter = riscv64_system_filter;
+static const size_t primary_system_filter_size = riscv64_system_filter_size;
+
+static const long primary_setresgid = __riscv64_setresgid;
+static const long primary_setresuid = __riscv64_setresuid;
+
#else
#error No architecture was defined!
#endif
@@ -98,7 +112,7 @@
f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_nr));
}
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_ARCH)
static bool SetValidateArchitectureJumpTarget(size_t offset, filter& f) {
size_t jump_length = f.size() - offset - 1;
auto u8_jump_length = (__u8) jump_length;
@@ -149,9 +163,17 @@
// that's the only system call we need to check here. A CTS test ensures the other
// calls will remain blocked.
static void ValidateSetUidGid(filter& f, uint32_t uid_gid_min, uint32_t uid_gid_max, bool primary) {
+#if defined(SECONDARY_ARCH)
+ __u32 setresuid_nr = primary ? primary_setresuid : secondary_setresuid;
+ __u32 setresgid_nr = primary ? primary_setresgid : secondary_setresgid;
+#else
+ __u32 setresuid_nr = primary_setresuid;
+ __u32 setresgid_nr = primary_setresgid;
+ UNUSED(primary);
+#endif
+
// Check setresuid(ruid, euid, sguid) fall within range
ExamineSyscall(f);
- __u32 setresuid_nr = primary ? primary_setresuid : secondary_setresuid;
f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, setresuid_nr, 0, 12));
for (int arg = 0; arg < 3; arg++) {
ValidateSyscallArgInRange(f, arg, uid_gid_min, uid_gid_max);
@@ -159,7 +181,6 @@
// Check setresgid(rgid, egid, sgid) fall within range
ExamineSyscall(f);
- __u32 setresgid_nr = primary ? primary_setresgid : secondary_setresgid;
f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, setresgid_nr, 0, 12));
for (int arg = 0; arg < 3; arg++) {
ValidateSyscallArgInRange(f, arg, uid_gid_min, uid_gid_max);
@@ -184,7 +205,7 @@
bool _install_setuidgid_filter(uint32_t uid_gid_min, uint32_t uid_gid_max) {
filter f;
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_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
// 32 bit syscalls will not hit the policy between here and the call to SetJump
@@ -195,7 +216,7 @@
ValidateSetUidGid(f, uid_gid_min, uid_gid_max, true /* primary */);
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_ARCH)
if (!SetValidateArchitectureJumpTarget(offset_to_secondary_filter, f)) {
return false;
}
@@ -213,32 +234,43 @@
};
bool _set_seccomp_filter(FilterType type) {
- const sock_filter *p, *s;
- size_t p_size, s_size;
filter f;
+ const sock_filter* p;
+ size_t p_size;
+#if defined(SECONDARY_ARCH)
+ const sock_filter* s;
+ size_t s_size;
+#endif
+
switch (type) {
case APP:
p = primary_app_filter;
p_size = primary_app_filter_size;
+#if defined(SECONDARY_ARCH)
s = secondary_app_filter;
s_size = secondary_app_filter_size;
+#endif
break;
case APP_ZYGOTE:
p = primary_app_zygote_filter;
p_size = primary_app_zygote_filter_size;
+#if defined(SECONDARY_ARCH)
s = secondary_app_zygote_filter;
s_size = secondary_app_zygote_filter_size;
+#endif
break;
case SYSTEM:
p = primary_system_filter;
p_size = primary_system_filter_size;
+#if defined(SECONDARY_ARCH)
s = secondary_system_filter;
s_size = secondary_system_filter_size;
+#endif
break;
}
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_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
// 32 bit syscalls will not hit the policy between here and the call to SetJump
@@ -254,7 +286,7 @@
}
Disallow(f);
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_ARCH)
if (!SetValidateArchitectureJumpTarget(offset_to_secondary_filter, f)) {
return false;
}
diff --git a/libc/stdio/printf_common.h b/libc/stdio/printf_common.h
index 4dc5ca1..e761835 100644
--- a/libc/stdio/printf_common.h
+++ b/libc/stdio/printf_common.h
@@ -524,6 +524,8 @@
case 'u':
case 'X':
case 'x':
+ case 'B':
+ case 'b':
ADDUARG();
break;
default: /* "%?" prints ?, unless ? is NUL */
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 08df2eb..27813a6 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -1129,7 +1129,9 @@
// Read directly into the caller's buffer.
while (total > 0) {
- ssize_t bytes_read = (*fp->_read)(fp->_cookie, dst, total);
+ // The _read function pointer takes an int instead of a size_t.
+ int chunk_size = MIN(total, INT_MAX);
+ ssize_t bytes_read = (*fp->_read)(fp->_cookie, dst, chunk_size);
if (bytes_read <= 0) {
fp->_flags |= (bytes_read == 0) ? __SEOF : __SERR;
break;
diff --git a/libc/stdio/stdio_ext.cpp b/libc/stdio/stdio_ext.cpp
index 945813e..99a8af7 100644
--- a/libc/stdio/stdio_ext.cpp
+++ b/libc/stdio/stdio_ext.cpp
@@ -67,6 +67,12 @@
return fp->_p - fp->_bf._base;
}
+size_t __freadahead(FILE* fp) {
+ // Normally _r is the amount of input already available.
+ // When there's ungetc() data, _r counts that and _ur is the previous _r.
+ return fp->_r + (HASUB(fp) ? fp->_ur : 0);
+}
+
void _flushlbf() {
// If we flush all streams, we know we've flushed all the line-buffered streams.
fflush(nullptr);
diff --git a/libc/stdio/vfprintf.cpp b/libc/stdio/vfprintf.cpp
index d99d09c..d83a5bf 100644
--- a/libc/stdio/vfprintf.cpp
+++ b/libc/stdio/vfprintf.cpp
@@ -81,8 +81,8 @@
char* dtoaresult = nullptr;
uintmax_t _umax; /* integer arguments %[diouxX] */
- enum { OCT, DEC, HEX } base; /* base for %[diouxX] conversion */
- int dprec; /* a copy of prec if %[diouxX], 0 otherwise */
+ enum { BIN, OCT, DEC, HEX } base; /* base for %[bBdiouxX] conversion */
+ int dprec; /* a copy of prec if %[bBdiouxX], 0 otherwise */
int realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */
const char* xdigs; /* digits for %[xX] conversion */
@@ -304,6 +304,12 @@
case 'z':
flags |= SIZEINT;
goto rflag;
+ case 'B':
+ case 'b':
+ _umax = UARG();
+ base = BIN;
+ if (flags & ALT && _umax != 0) ox[1] = ch;
+ goto nosign;
case 'C':
flags |= LONGINT;
__BIONIC_FALLTHROUGH;
@@ -550,6 +556,13 @@
* a variable; hence this switch.
*/
switch (base) {
+ case BIN:
+ do {
+ *--cp = to_char(_umax & 1);
+ _umax >>= 1;
+ } while (_umax);
+ break;
+
case OCT:
do {
*--cp = to_char(_umax & 7);
@@ -599,7 +612,7 @@
* first be prefixed by any sign or other prefix; otherwise,
* it should be blank padded before the prefix is emitted.
* After any left-hand padding and prefixing, emit zeroes
- * required by a decimal %[diouxX] precision, then print the
+ * required by a decimal %[bBdiouxX] precision, then print the
* string proper, then emit zeroes required by any leftover
* floating precision; finally, if LADJUST, pad with blanks.
*
diff --git a/libc/stdio/vfscanf.cpp b/libc/stdio/vfscanf.cpp
index 424c4ef..d05a3a6 100644
--- a/libc/stdio/vfscanf.cpp
+++ b/libc/stdio/vfscanf.cpp
@@ -69,7 +69,8 @@
#define HAVESIGN 0x04000 // Sign detected
#define NDIGITS 0x08000 // No digits detected
#define PFXOK 0x10000 // "0x" prefix is (still) legal
-#define NZDIGITS 0x20000 // No zero digits detected
+#define PFBOK 0x20000 // "0b" prefix is (still) legal
+#define NZDIGITS 0x40000 // No zero digits detected
// Conversion types.
#define CT_CHAR 0 // %c conversion
@@ -101,9 +102,6 @@
void* allocation = nullptr; // Allocated but unassigned result for %mc/%ms/%m[.
size_t capacity = 0; // Number of char/wchar_t units allocated in `allocation`.
- /* `basefix' is used to avoid `if' tests in the integer scanner */
- static short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
-
_SET_ORIENTATION(fp, -1);
nassigned = 0;
@@ -188,6 +186,12 @@
* Conversions.
* Those marked `compat' are for 4.[123]BSD compatibility.
*/
+ case 'b':
+ c = CT_INT;
+ base = 2;
+ flags |= PFBOK; /* enable 0b prefixing */
+ break;
+
case 'D': /* compat */
flags |= LONG;
__BIONIC_FALLTHROUGH;
@@ -558,7 +562,7 @@
* digits (zero or nonzero) have been
* scanned (only signs), we will have
* base==0. In that case, we should set
- * it to 8 and enable 0x prefixing.
+ * it to 8 and enable 0b/0x prefixing.
* Also, if we have not scanned zero digits
* before this, do not turn off prefixing
* (someone else will turn it off if we
@@ -567,15 +571,24 @@
case '0':
if (base == 0) {
base = 8;
- flags |= PFXOK;
+ flags |= PFBOK | PFXOK;
}
- if (flags & NZDIGITS)
+ if (flags & NZDIGITS) {
flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
- else
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ } else {
+ flags &= ~(SIGNOK | PFBOK | PFXOK | NDIGITS);
+ }
goto ok;
-
- /* 1 through 7 always legal */
+ case 'B':
+ case 'b':
+ // Is this 'b' or 'B' potentially part of an "0b" prefix?
+ if ((flags & PFBOK) && p == buf + 1 + !!(flags & HAVESIGN)) {
+ base = 2;
+ flags &= ~PFBOK;
+ goto ok;
+ }
+ // No? Fall through and see if it's a hex digit instead then...
+ __BIONIC_FALLTHROUGH;
case '1':
case '2':
case '3':
@@ -583,34 +596,21 @@
case '5':
case '6':
case '7':
- base = basefix[base];
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* digits 8 and 9 ok iff decimal or hex */
case '8':
case '9':
- base = basefix[base];
- if (base <= 8) break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* letters ok iff hex */
case 'A':
- case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'a':
- case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
- /* no need to fix base here */
- if (base <= 10) break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ if (base == 0) base = 10;
+ if (base != 16 && (c - '0') >= base) break; /* not legal here */
+ flags &= ~(SIGNOK | PFBOK | PFXOK | NDIGITS);
goto ok;
/* sign ok only as first character */
@@ -653,17 +653,16 @@
break; /* EOF */
}
/*
- * If we had only a sign, it is no good; push
- * back the sign. If the number ends in `x',
- * it was [sign] '0' 'x', so push back the x
- * and treat it as [sign] '0'.
+ * If we had only a sign, it is no good; push back the sign.
+ * If the number was `[-+]0[BbXx]`, push back and treat it
+ * as `[-+]0`.
*/
if (flags & NDIGITS) {
if (p > buf) (void)ungetc(*(u_char*)--p, fp);
goto match_failure;
}
c = ((u_char*)p)[-1];
- if (c == 'x' || c == 'X') {
+ if ((base == 2 && (c == 'b' || c == 'B')) || c == 'x' || c == 'X') {
--p;
(void)ungetc(c, fp);
}
diff --git a/libc/stdio/vfwprintf.cpp b/libc/stdio/vfwprintf.cpp
index dd51eec..9819a73 100644
--- a/libc/stdio/vfwprintf.cpp
+++ b/libc/stdio/vfwprintf.cpp
@@ -81,8 +81,8 @@
char* dtoaresult = nullptr;
uintmax_t _umax; /* integer arguments %[diouxX] */
- enum { OCT, DEC, HEX } base; /* base for %[diouxX] conversion */
- int dprec; /* a copy of prec if %[diouxX], 0 otherwise */
+ enum { BIN, OCT, DEC, HEX } base; /* base for %[bBdiouxX] conversion */
+ int dprec; /* a copy of prec if %[bBdiouxX], 0 otherwise */
int realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */
const char* xdigs; /* digits for %[xX] conversion */
@@ -293,6 +293,12 @@
case 'z':
flags |= SIZEINT;
goto rflag;
+ case 'B':
+ case 'b':
+ _umax = UARG();
+ base = BIN;
+ if (flags & ALT && _umax != 0) ox[1] = ch;
+ goto nosign;
case 'C':
flags |= LONGINT;
__BIONIC_FALLTHROUGH;
@@ -539,6 +545,13 @@
* a variable; hence this switch.
*/
switch (base) {
+ case BIN:
+ do {
+ *--cp = to_char(_umax & 1);
+ _umax >>= 1;
+ } while (_umax);
+ break;
+
case OCT:
do {
*--cp = to_char(_umax & 7);
@@ -588,7 +601,7 @@
* first be prefixed by any sign or other prefix; otherwise,
* it should be blank padded before the prefix is emitted.
* After any left-hand padding and prefixing, emit zeroes
- * required by a decimal %[diouxX] precision, then print the
+ * required by a decimal %[bBdiouxX] precision, then print the
* string proper, then emit zeroes required by any leftover
* floating precision; finally, if LADJUST, pad with blanks.
*
diff --git a/libc/stdio/vfwscanf.c b/libc/stdio/vfwscanf.cpp
similarity index 91%
rename from libc/stdio/vfwscanf.c
rename to libc/stdio/vfwscanf.cpp
index 71cd49b..06f706a 100644
--- a/libc/stdio/vfwscanf.c
+++ b/libc/stdio/vfwscanf.cpp
@@ -42,6 +42,8 @@
#include <wctype.h>
#include "local.h"
+#include <platform/bionic/macros.h>
+
#define BUF 513 /* Maximum length of numeric string. */
/*
@@ -65,15 +67,16 @@
* SIGNOK, HAVESIGN, NDIGITS, DPTOK, and EXPOK are for floating point;
* SIGNOK, HAVESIGN, NDIGITS, PFXOK, and NZDIGITS are for integral.
*/
-#define SIGNOK 0x01000 /* +/- is (still) legal */
+#define SIGNOK 0x01000 /* +/- is (still) legal */
#define HAVESIGN 0x02000 /* sign detected */
-#define NDIGITS 0x04000 /* no digits detected */
+#define NDIGITS 0x04000 /* no digits detected */
-#define DPTOK 0x08000 /* (float) decimal point is still legal */
-#define EXPOK 0x10000 /* (float) exponent (e+3, etc) still legal */
+#define DPTOK 0x08000 /* (float) decimal point is still legal */
+#define EXPOK 0x10000 /* (float) exponent (e+3, etc) still legal */
-#define PFXOK 0x08000 /* 0x prefix is (still) legal */
-#define NZDIGITS 0x10000 /* no zero digits detected */
+#define PFBOK 0x20000 /* 0x prefix is (still) legal */
+#define PFXOK 0x40000 /* 0x prefix is (still) legal */
+#define NZDIGITS 0x80000 /* no zero digits detected */
/*
* Conversion types.
@@ -147,9 +150,6 @@
char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
mbstate_t mbs;
- /* `basefix' is used to avoid `if' tests in the integer scanner */
- static short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
-
_SET_ORIENTATION(fp, 1);
nassigned = 0;
@@ -239,9 +239,15 @@
* Conversions.
* Those marked `compat' are for 4.[123]BSD compatibility.
*/
+ case 'b':
+ c = CT_INT;
+ base = 2;
+ flags |= PFBOK; /* enable 0b prefixing */
+ break;
+
case 'D': /* compat */
flags |= LONG;
- /* FALLTHROUGH */
+ __BIONIC_FALLTHROUGH;
case 'd':
c = CT_INT;
base = 10;
@@ -254,7 +260,7 @@
case 'O': /* compat */
flags |= LONG;
- /* FALLTHROUGH */
+ __BIONIC_FALLTHROUGH;
case 'o':
c = CT_INT;
flags |= UNSIGNED;
@@ -468,7 +474,7 @@
* digits (zero or nonzero) have been
* scanned (only signs), we will have
* base==0. In that case, we should set
- * it to 8 and enable 0x prefixing.
+ * it to 8 and enable 0b/0x prefixing.
* Also, if we have not scanned zero digits
* before this, do not turn off prefixing
* (someone else will turn it off if we
@@ -477,15 +483,26 @@
case '0':
if (base == 0) {
base = 8;
- flags |= PFXOK;
+ flags |= PFBOK | PFXOK;
}
- if (flags & NZDIGITS)
+ if (flags & NZDIGITS) {
flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
- else
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ } else {
+ flags &= ~(SIGNOK | PFBOK | PFXOK | NDIGITS);
+ }
goto ok;
/* 1 through 7 always legal */
+ case 'B':
+ case 'b':
+ // Is this 'b' potentially part of an "0b" prefix?
+ if ((flags & PFBOK) && p == buf + 1 + !!(flags & HAVESIGN)) {
+ base = 2;
+ flags &= ~PFBOK;
+ goto ok;
+ }
+ // No? Fall through and see if it's a hex digit instead then...
+ __BIONIC_FALLTHROUGH;
case '1':
case '2':
case '3':
@@ -493,34 +510,21 @@
case '5':
case '6':
case '7':
- base = basefix[base];
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* digits 8 and 9 ok iff decimal or hex */
case '8':
case '9':
- base = basefix[base];
- if (base <= 8) break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
-
- /* letters ok iff hex */
case 'A':
- case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'a':
- case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
- /* no need to fix base here */
- if (base <= 10) break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ if (base == 0) base = 10;
+ if (base != 16 && (int)(c - '0') >= base) break; /* not legal here */
+ flags &= ~(SIGNOK | PFBOK | PFXOK | NDIGITS);
goto ok;
/* sign ok only as first character */
@@ -560,17 +564,16 @@
*p++ = (wchar_t)c;
}
/*
- * If we had only a sign, it is no good; push
- * back the sign. If the number ends in `x',
- * it was [sign] '0' 'x', so push back the x
- * and treat it as [sign] '0'.
+ * If we had only a sign, it is no good; push back the sign.
+ * If the number was `[-+]0[BbXx]`, push back and treat it
+ * as `[-+]0`.
*/
if (flags & NDIGITS) {
if (p > buf) __ungetwc(*--p, fp);
goto match_failure;
}
c = p[-1];
- if (c == 'x' || c == 'X') {
+ if ((base == 2 && (c == 'b' || c == 'B')) || c == 'x' || c == 'X') {
--p;
__ungetwc(c, fp);
}
diff --git a/libc/tools/Android.bp b/libc/tools/Android.bp
index 116b853..c7fce64 100644
--- a/libc/tools/Android.bp
+++ b/libc/tools/Android.bp
@@ -8,8 +8,8 @@
default_applicable_licenses: ["bionic_libc_license"],
}
-filegroup {
- name: "bionic-gensyscalls",
+python_binary_host {
+ name: "gensyscalls",
srcs: ["gensyscalls.py"],
}
diff --git a/libc/tools/genfunctosyscallnrs.py b/libc/tools/genfunctosyscallnrs.py
index fa48844..9b8f7ee 100755
--- a/libc/tools/genfunctosyscallnrs.py
+++ b/libc/tools/genfunctosyscallnrs.py
@@ -21,12 +21,12 @@
def gen_syscall_nrs(out_file, base_syscall_file, syscall_NRs):
- for arch in SupportedArchitectures:
+ for arch in syscall_NRs.keys():
base_names = load_syscall_names_from_file(base_syscall_file, arch)
for func, syscall in base_names.items():
out_file.write("#define __" + arch + "_" + func + " " +
- str(syscall_NRs[arch][syscall]) + ";\n")
+ str(syscall_NRs[arch][syscall]) + "\n")
def main():
diff --git a/libc/tools/genseccomp.py b/libc/tools/genseccomp.py
index 33bf470..8a07caf 100755
--- a/libc/tools/genseccomp.py
+++ b/libc/tools/genseccomp.py
@@ -5,9 +5,10 @@
import operator
import os
import re
+import sys
import textwrap
-from gensyscalls import SupportedArchitectures, SysCallsTxtParser
+from gensyscalls import SysCallsTxtParser
BPF_JGE = "BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, {0}, {1}, {2})"
@@ -84,42 +85,46 @@
# #define __(ARM_)?NR_${NAME} ${VALUE}
#
# Where ${VALUE} is a preprocessor expression.
+ #
+ # Newer architectures have things like this though:
+ #
+ # #define __NR3264_fcntl 25
+ # #define __NR_fcntl __NR3264_fcntl
+ #
+ # So we need to keep track of the __NR3264_* constants and substitute them.
- constant_re = re.compile(
- r'^\s*#define\s+([A-Za-z_][A-Za-z0-9_]+)\s+(.+)\s*$')
+ line_re = re.compile(r'^# \d+ ".*".*')
+ undef_re = re.compile(r'^#undef\s.*')
+ define_re = re.compile(r'^\s*#define\s+([A-Za-z0-9_(,)]+)(?:\s+(.+))?\s*$')
token_re = re.compile(r'\b[A-Za-z_][A-Za-z0-9_]+\b')
constants = {}
+ nr3264s = {}
with open(names_path) as f:
for line in f:
- m = constant_re.match(line)
- if m is None:
- continue
- try:
+ line = line.strip()
+ m = define_re.match(line)
+ if m:
name = m.group(1)
- # eval() takes care of any arithmetic that may be done
- value = eval(token_re.sub(lambda x: str(constants[x.group(0)]),
- m.group(2)))
+ value = m.group(2)
+ if name.startswith('__NR3264'):
+ nr3264s[name] = value
+ elif name.startswith('__NR_') or name.startswith('__ARM_NR_'):
+ if value in nr3264s:
+ value = nr3264s[value]
+ # eval() takes care of any arithmetic that may be done
+ value = eval(token_re.sub(lambda x: str(constants[x.group(0)]), value))
- constants[name] = value
- except: # pylint: disable=bare-except
- # TODO: This seems wrong.
- # Key error doesn't seem like the error the original author was trying
- # to catch. It looks like the intent was to catch IndexError from
- # match.group() for non-matching lines, but that's impossible because
- # the match object is checked and continued if not matched. What
- # actually happens is that KeyError is thrown by constants[x.group(0)]
- # on at least the first run because the dict is empty.
- #
- # It's also matching syntax errors because not all C integer literals
- # are valid Python integer literals, e.g. 10L.
- logging.debug('Failed to parse %s', line)
+ constants[name] = value
+ else:
+ if not line_re.match(line) and not undef_re.match(line) and line:
+ print('%s: failed to parse line `%s`' % (names_path, line))
+ sys.exit(1)
syscalls = {}
for name, value in constants.items():
- if not name.startswith("__NR_") and not name.startswith("__ARM_NR"):
- continue
+ # Remove the __NR_ prefix.
+ # TODO: why not __ARM_NR too?
if name.startswith("__NR_"):
- # Remote the __NR_ prefix
name = name[len("__NR_"):]
syscalls[name] = value
@@ -237,7 +242,7 @@
def gen_policy(name_modifier, out_dir, base_syscall_file, syscall_files,
syscall_NRs, priority_file):
- for arch in SupportedArchitectures:
+ for arch in syscall_NRs.keys():
base_names = load_syscall_names_from_file(base_syscall_file, arch)
allowlist_names = set()
blocklist_names = set()
@@ -251,11 +256,11 @@
priorities = load_syscall_priorities_from_file(priority_file)
allowed_syscalls = []
- for name in merge_names(base_names, allowlist_names, blocklist_names):
+ for name in sorted(merge_names(base_names, allowlist_names, blocklist_names)):
try:
allowed_syscalls.append((name, syscall_NRs[arch][name]))
except:
- logging.exception("Failed to find %s in %s", name, arch)
+ logging.exception("Failed to find %s in %s (%s)", name, arch, syscall_NRs[arch])
raise
output = construct_bpf(allowed_syscalls, arch, name_modifier, priorities)
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index baaa52d..d3e6ef4 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -15,7 +15,7 @@
import tempfile
-SupportedArchitectures = [ "arm", "arm64", "x86", "x86_64" ]
+SupportedArchitectures = [ "arm", "arm64", "riscv64", "x86", "x86_64" ]
syscall_stub_header = \
"""
@@ -80,6 +80,24 @@
#
+# RISC-V64 assembler templates for each syscall stub
+#
+
+riscv64_call = syscall_stub_header + """\
+ li a7, %(__NR_name)s
+ ecall
+
+ li a7, -MAX_ERRNO
+ bgtu a0, a7, 1f
+
+ ret
+1:
+ neg a0, a0
+ j __set_errno_internal
+END(%(func)s)
+"""
+
+#
# x86 assembler templates for each syscall stub
#
@@ -228,6 +246,10 @@
return arm64_call % syscall
+def riscv64_genstub(syscall):
+ return riscv64_call % syscall
+
+
def x86_genstub(syscall):
result = syscall_stub_header % syscall
@@ -440,6 +462,9 @@
if "arm64" in syscall:
syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall)
+ if "riscv64" in syscall:
+ syscall["asm-riscv64"] = add_footer(64, riscv64_genstub(syscall), syscall)
+
if "x86" in syscall:
if syscall["socketcall_id"] >= 0:
syscall["asm-x86"] = add_footer(32, x86_genstub_socketcall(syscall), syscall)
diff --git a/libc/tzcode/asctime.c b/libc/tzcode/asctime.c
index 337a313..ce5d4be 100644
--- a/libc/tzcode/asctime.c
+++ b/libc/tzcode/asctime.c
@@ -1,3 +1,5 @@
+/* asctime and asctime_r a la POSIX and ISO C, except pad years before 1000. */
+
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson.
@@ -12,7 +14,7 @@
/*LINTLIBRARY*/
#include "private.h"
-#include "tzfile.h"
+#include <stdio.h>
/*
** Some systems only handle "%.2d"; others only handle "%02d";
@@ -29,13 +31,13 @@
** leading zeroes to get the newline in the traditional place.
** The -4 ensures that we get four characters of output even if
** we call a strftime variant that produces fewer characters for some years.
-** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year,
+** The ISO C and POSIX standards prohibit padding the year,
** but many implementations pad anyway; most likely the standards are buggy.
*/
#ifdef __GNUC__
-#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n"
+#define ASCTIME_FMT "%s %s%3d %2.2d:%2.2d:%2.2d %-4s\n"
#else /* !defined __GNUC__ */
-#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n"
+#define ASCTIME_FMT "%s %s%3d %02.2d:%02.2d:%02.2d %-4s\n"
#endif /* !defined __GNUC__ */
/*
** For years that are more than four digits we put extra spaces before the year
@@ -44,9 +46,9 @@
** that no output is better than wrong output).
*/
#ifdef __GNUC__
-#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n"
+#define ASCTIME_FMT_B "%s %s%3d %2.2d:%2.2d:%2.2d %s\n"
#else /* !defined __GNUC__ */
-#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n"
+#define ASCTIME_FMT_B "%s %s%3d %02.2d:%02.2d:%02.2d %s\n"
#endif /* !defined __GNUC__ */
#define STD_ASCTIME_BUF_SIZE 26
@@ -64,17 +66,13 @@
static char buf_asctime[MAX_ASCTIME_BUF_SIZE];
-/*
-** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
-*/
-
char *
asctime_r(register const struct tm *timeptr, char *buf)
{
- static const char wday_name[][3] = {
+ static const char wday_name[][4] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
- static const char mon_name[][3] = {
+ static const char mon_name[][4] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
@@ -117,10 +115,6 @@
}
}
-/*
-** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
-*/
-
char *
asctime(register const struct tm *timeptr)
{
diff --git a/libc/tzcode/bionic.cpp b/libc/tzcode/bionic.cpp
index e134aaa..d2b5d80 100644
--- a/libc/tzcode/bionic.cpp
+++ b/libc/tzcode/bionic.cpp
@@ -190,6 +190,18 @@
// Give up now, and don't try fallback tzdata files. We don't log here
// because for all we know the given olson id was nonsense.
close(fd);
+ // This file descriptor (-1) is passed to localtime.c. In invalid fd case
+ // upstream passes errno value around methods and having 0 there will
+ // indicate that time zone was found and read successfully and localtime's
+ // internal state was properly initialized (which wasn't as we couldn't find
+ // requested time zone in the tzdata file).
+ // If we reached this point errno is unlikely to be touched. It is only
+ // close(fd) which can do it, but that is very unlikely to happen. And
+ // even if it happens we can't extract any useful insights from it.
+ // We are overriding it to ENOENT as it matches upstream expectations -
+ // time zone is absent in the tzdata file == there is no TZif file in
+ // /usr/share/zoneinfo.
+ errno = ENOENT;
return -1;
}
@@ -206,24 +218,14 @@
int __bionic_open_tzdata(const char* olson_id, int32_t* entry_length) {
int fd;
- // Try the three locations for the tzdata file in a strict order:
- // 1: The O-MR1 time zone updates via APK update mechanism. This is
- // tried first because it allows us to test that the time zone updates
- // via APK mechanism still works even on devices with the time zone
- // module.
- // TODO: remove this when those devices are no longer supported.
- // 2: The time zone data module which contains the main copy. This is the
+ // Try the two locations for the tzdata file in a strict order:
+ // 1: The time zone data module which contains the main copy. This is the
// common case for current devices.
- // 3: The ultimate fallback: the non-updatable copy in /system.
+ // 2: The ultimate fallback: the non-updatable copy in /system.
#if defined(__ANDROID__)
// On Android devices, bionic has to work even if exec takes place without
// environment variables set. So, all paths are hardcoded here.
-
- fd = __bionic_open_tzdata_path("/data/misc/zoneinfo/current/tzdata",
- olson_id, entry_length);
- if (fd >= -1) return fd;
-
fd = __bionic_open_tzdata_path("/apex/com.android.tzdata/etc/tz/tzdata",
olson_id, entry_length);
if (fd >= -1) return fd;
@@ -233,16 +235,10 @@
if (fd >= -1) return fd;
#else
// On the host, we don't expect the hard-coded locations above to exist, and
- // we're not worried about security so we trust $ANDROID_DATA,
- // $ANDROID_TZDATA_ROOT, and $ANDROID_ROOT to point us in the right direction
- // instead.
+ // we're not worried about security so we trust $ANDROID_TZDATA_ROOT, and
+ // $ANDROID_ROOT to point us in the right direction instead.
- char* path = make_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata");
- fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
- free(path);
- if (fd >= -1) return fd;
-
- path = make_path("ANDROID_TZDATA_ROOT", "/etc/tz/tzdata");
+ char* path = make_path("ANDROID_TZDATA_ROOT", "/etc/tz/tzdata");
fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
free(path);
if (fd >= -1) return fd;
diff --git a/libc/tzcode/difftime.c b/libc/tzcode/difftime.c
index ba2fd03..ff78f03 100644
--- a/libc/tzcode/difftime.c
+++ b/libc/tzcode/difftime.c
@@ -1,3 +1,5 @@
+/* Return the difference between two timestamps. */
+
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson.
@@ -14,14 +16,14 @@
return -x;
}
-double ATTRIBUTE_CONST
+double
difftime(time_t time1, time_t time0)
{
/*
** If double is large enough, simply convert and subtract
** (assuming that the larger type has more precision).
*/
- if (sizeof (time_t) < sizeof (double)) {
+ if (sizeof(time_t) < sizeof(double)) {
double t1 = time1, t0 = time0;
return t1 - t0;
}
@@ -34,7 +36,7 @@
return time0 <= time1 ? time1 - time0 : dminus(time0 - time1);
/* Use uintmax_t if wide enough. */
- if (sizeof (time_t) <= sizeof (uintmax_t)) {
+ if (sizeof(time_t) <= sizeof(uintmax_t)) {
uintmax_t t1 = time1, t0 = time0;
return time0 <= time1 ? t1 - t0 : dminus(t0 - t1);
}
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 091bab0..8ff5cee 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -1,3 +1,5 @@
+/* Convert timestamp from time_t to struct tm. */
+
/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson.
@@ -14,9 +16,9 @@
#include "private.h"
#include "tzfile.h"
-#include "fcntl.h"
+#include <fcntl.h>
-#if THREAD_SAFE
+#if defined THREAD_SAFE && THREAD_SAFE
# include <pthread.h>
static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER;
static int lock(void) { return pthread_mutex_lock(&locallock); }
@@ -26,14 +28,6 @@
static void unlock(void) { }
#endif
-/* NETBSD_INSPIRED_EXTERN functions are exported to callers if
- NETBSD_INSPIRED is defined, and are private otherwise. */
-#if NETBSD_INSPIRED
-# define NETBSD_INSPIRED_EXTERN
-#else
-# define NETBSD_INSPIRED_EXTERN static
-#endif
-
#ifndef TZ_ABBR_MAX_LEN
#define TZ_ABBR_MAX_LEN 16
#endif /* !defined TZ_ABBR_MAX_LEN */
@@ -87,31 +81,39 @@
/*
** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
-** We default to US rules as of 1999-08-17.
-** POSIX 1003.1 section 8.1.1 says that the default DST rules are
-** implementation dependent; for historical reasons, US rules are a
-** common default.
+** Default to US rules as of 2017-05-07.
+** POSIX does not specify the default DST rules;
+** for historical reasons, US rules are a common default.
*/
#ifndef TZDEFRULESTRING
-#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
-#endif /* !defined TZDEFDST */
+#define TZDEFRULESTRING ",M3.2.0,M11.1.0"
+#endif
struct ttinfo { /* time type information */
- int_fast32_t tt_gmtoff; /* UT offset in seconds */
+ int_fast32_t tt_utoff; /* UT offset in seconds */
bool tt_isdst; /* used to set tm_isdst */
- int tt_abbrind; /* abbreviation list index */
+ int tt_desigidx; /* abbreviation list index */
bool tt_ttisstd; /* transition is std time */
- bool tt_ttisgmt; /* transition is UT */
+ bool tt_ttisut; /* transition is UT */
};
struct lsinfo { /* leap second information */
time_t ls_trans; /* transition time */
- int_fast64_t ls_corr; /* correction to apply */
+ int_fast32_t ls_corr; /* correction to apply */
};
#define SMALLEST(a, b) (((a) < (b)) ? (a) : (b))
#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
+/* This abbreviation means local time is unspecified. */
+static char const UNSPEC[] = "-00";
+
+/* How many extra bytes are needed at the end of struct state's chars array.
+ This needs to be at least 1 for null termination in case the input
+ data isn't properly terminated, and it also needs to be big enough
+ for ttunspecified to work without crashing. */
+enum { CHARS_EXTRA = BIGGEST(sizeof UNSPEC, 2) - 1 };
+
#ifdef TZNAME_MAX
#define MY_TZNAME_MAX TZNAME_MAX
#endif /* defined TZNAME_MAX */
@@ -129,10 +131,14 @@
time_t ats[TZ_MAX_TIMES];
unsigned char types[TZ_MAX_TIMES];
struct ttinfo ttis[TZ_MAX_TYPES];
- char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
+ char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + CHARS_EXTRA,
+ sizeof gmt),
(2 * (MY_TZNAME_MAX + 1)))];
struct lsinfo lsis[TZ_MAX_LEAPS];
- int defaulttype; /* for early times or if no transitions */
+ /* The time type to use for early times or if no transitions.
+ It is always zero for recent tzdb releases.
+ It might be nonzero for data from tzdb 2018e or earlier. */
+ int defaulttype;
};
enum r_type {
@@ -153,11 +159,12 @@
struct tm *);
static bool increment_overflow(int *, int);
static bool increment_overflow_time(time_t *, int_fast32_t);
+static int_fast32_t leapcorr(struct state const *, time_t);
static bool normalize_overflow32(int_fast32_t *, int *, int);
static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
struct tm *);
static bool typesequiv(struct state const *, int, int);
-static bool tzparse(char const *, struct state *, bool);
+static bool tzparse(char const *, struct state *, struct state *);
#ifdef ALL_STATE
static struct state * lclptr;
@@ -188,30 +195,39 @@
static struct tm tm;
-#if !HAVE_POSIX_DECLS
+#if 2 <= HAVE_TZNAME + TZ_TIME_T
char * tzname[2] = {
(char *) wildabbr,
(char *) wildabbr
};
-#ifdef USG_COMPAT
+#endif
+#if 2 <= USG_COMPAT + TZ_TIME_T
long timezone;
int daylight;
-# endif
#endif
-#ifdef ALTZONE
+#if 2 <= ALTZONE + TZ_TIME_T
long altzone;
-#endif /* defined ALTZONE */
+#endif
-/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */
+/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
static void
-init_ttinfo(struct ttinfo *s, int_fast32_t gmtoff, bool isdst, int abbrind)
+init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
{
- s->tt_gmtoff = gmtoff;
+ s->tt_utoff = utoff;
s->tt_isdst = isdst;
- s->tt_abbrind = abbrind;
+ s->tt_desigidx = desigidx;
s->tt_ttisstd = false;
- s->tt_ttisgmt = false;
+ s->tt_ttisut = false;
+}
+
+/* Return true if SP's time type I does not specify local time. */
+static bool
+ttunspecified(struct state const *sp, int i)
+{
+ char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx];
+ /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */
+ return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0;
}
static int_fast32_t
@@ -240,7 +256,7 @@
static int_fast64_t
detzcode64(const char *const codep)
{
- register uint_fast64_t result;
+ register int_fast64_t result;
register int i;
int_fast64_t one = 1;
int_fast64_t halfmaxval = one << (64 - 2);
@@ -263,52 +279,71 @@
static void
update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
{
- tzname[ttisp->tt_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];
-#ifdef USG_COMPAT
+#if HAVE_TZNAME
+ tzname[ttisp->tt_isdst] = (char *) &sp->chars[ttisp->tt_desigidx];
+#endif
+#if USG_COMPAT
if (!ttisp->tt_isdst)
- timezone = - ttisp->tt_gmtoff;
+ timezone = - ttisp->tt_utoff;
#endif
-#ifdef ALTZONE
+#if ALTZONE
if (ttisp->tt_isdst)
- altzone = - ttisp->tt_gmtoff;
+ altzone = - ttisp->tt_utoff;
#endif
}
+/* If STDDST_MASK indicates that SP's TYPE provides useful info,
+ update tzname, timezone, and/or altzone and return STDDST_MASK,
+ diminished by the provided info if it is a specified local time.
+ Otherwise, return STDDST_MASK. See settzname for STDDST_MASK. */
+static int
+may_update_tzname_etc(int stddst_mask, struct state *sp, int type)
+{
+ struct ttinfo *ttisp = &sp->ttis[type];
+ int this_bit = 1 << ttisp->tt_isdst;
+ if (stddst_mask & this_bit) {
+ update_tzname_etc(sp, ttisp);
+ if (!ttunspecified(sp, type))
+ return stddst_mask & ~this_bit;
+ }
+ return stddst_mask;
+}
+
static void
settzname(void)
{
register struct state * const sp = lclptr;
register int i;
- tzname[0] = tzname[1] = (char *) wildabbr;
-#ifdef USG_COMPAT
- daylight = 0;
+ /* If STDDST_MASK & 1 we need info about a standard time.
+ If STDDST_MASK & 2 we need info about a daylight saving time.
+ When STDDST_MASK becomes zero we can stop looking. */
+ int stddst_mask = 0;
+
+#if HAVE_TZNAME
+ tzname[0] = tzname[1] = (char *) (sp ? wildabbr : gmt);
+ stddst_mask = 3;
+#endif
+#if USG_COMPAT
timezone = 0;
-#endif /* defined USG_COMPAT */
-#ifdef ALTZONE
+ stddst_mask = 3;
+#endif
+#if ALTZONE
altzone = 0;
-#endif /* defined ALTZONE */
- if (sp == NULL) {
- tzname[0] = tzname[1] = (char *) gmt;
- return;
- }
+ stddst_mask |= 2;
+#endif
/*
- ** And to get the latest zone names into tzname. . .
+ ** And to get the latest time zone abbreviations into tzname. . .
*/
- for (i = 0; i < sp->typecnt; ++i) {
- register const struct ttinfo * const ttisp = &sp->ttis[i];
- update_tzname_etc(sp, ttisp);
+ if (sp) {
+ for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--)
+ stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]);
+ for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--)
+ stddst_mask = may_update_tzname_etc(stddst_mask, sp, i);
}
- for (i = 0; i < sp->timecnt; ++i) {
- register const struct ttinfo * const ttisp =
- &sp->ttis[
- sp->types[i]];
- update_tzname_etc(sp, ttisp);
-#ifdef USG_COMPAT
- if (ttisp->tt_isdst)
- daylight = 1;
-#endif /* defined USG_COMPAT */
- }
+#if USG_COMPAT
+ daylight = stddst_mask >> 1 ^ 1;
+#endif
}
static void
@@ -326,7 +361,7 @@
*/
for (i = 0; i < sp->typecnt; ++i) {
register const struct ttinfo * const ttisp = &sp->ttis[i];
- register char * cp = &sp->chars[ttisp->tt_abbrind];
+ char *cp = &sp->chars[ttisp->tt_desigidx];
if (strlen(cp) > TZ_ABBR_MAX_LEN &&
strcmp(cp, GRANDPARENTED) != 0)
@@ -334,39 +369,39 @@
}
}
-static bool
-differ_by_repeat(const time_t t1, const time_t t0)
-{
- if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
- return 0;
-#if defined(__LP64__) // 32-bit Android/glibc has a signed 32-bit time_t; 64-bit doesn't.
- return t1 - t0 == SECSPERREPEAT;
-#endif
-}
-
/* Input buffer for data read from a compiled tz file. */
union input_buffer {
/* The first part of the buffer, interpreted as a header. */
struct tzhead tzhead;
/* The entire buffer. */
- char buf[2 * sizeof(struct tzhead) + 2 * sizeof (struct state)
- + 4 * TZ_MAX_TIMES];
+ char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
+ + 4 * TZ_MAX_TIMES];
};
+// Android-removed: There is no directory with file-per-time zone on Android.
+#ifndef __BIONIC__
+/* TZDIR with a trailing '/' rather than a trailing '\0'. */
+static char const tzdirslash[sizeof TZDIR] = TZDIR "/";
+#endif
+
/* Local storage needed for 'tzloadbody'. */
union local_storage {
- /* The file name to be opened. */
- char fullname[FILENAME_MAX + 1];
-
/* The results of analyzing the file's contents after it is opened. */
- struct {
+ struct file_analysis {
/* The input buffer. */
union input_buffer u;
/* A temporary state used for parsing a TZ string in the file. */
struct state st;
} u;
+
+ // Android-removed: There is no directory with file-per-time zone on Android.
+ #ifndef __BIONIC__
+ /* The file name to be opened. */
+ char fullname[BIGGEST(sizeof(struct file_analysis),
+ sizeof tzdirslash + 1024)];
+ #endif
};
/* Load tz data from the file named NAME into *SP. Read extended
@@ -385,7 +420,7 @@
register char *fullname = lsp->fullname;
#endif
register union input_buffer *up = &lsp->u.u;
- register int tzheadsize = sizeof (struct tzhead);
+ register int tzheadsize = sizeof(struct tzhead);
sp->goback = sp->goahead = false;
@@ -402,20 +437,36 @@
#else
if (name[0] == ':')
++name;
+#ifdef SUPPRESS_TZDIR
+ /* Do not prepend TZDIR. This is intended for specialized
+ applications only, due to its security implications. */
+ doaccess = true;
+#else
doaccess = name[0] == '/';
+#endif
if (!doaccess) {
- char const *p = TZDIR;
- if (! p)
- return EINVAL;
- if (sizeof lsp->fullname - 1 <= strlen(p) + strlen(name))
+ char const *dot;
+ size_t namelen = strlen(name);
+ if (sizeof lsp->fullname - sizeof tzdirslash <= namelen)
return ENAMETOOLONG;
- strcpy(fullname, p);
- strcat(fullname, "/");
- strcat(fullname, name);
- /* Set doaccess if '.' (as in "../") shows up in name. */
- if (strchr(name, '.'))
- doaccess = true;
- name = fullname;
+
+ /* Create a string "TZDIR/NAME". Using sprintf here
+ would pull in stdio (and would fail if the
+ resulting string length exceeded INT_MAX!). */
+ memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash);
+ strcpy(lsp->fullname + sizeof tzdirslash, name);
+
+ /* Set doaccess if NAME contains a ".." file name
+ component, as such a name could read a file outside
+ the TZDIR virtual subtree. */
+ for (dot = name; (dot = strchr(dot, '.')); dot++)
+ if ((dot == name || dot[-1] == '/') && dot[1] == '.'
+ && (dot[2] == '/' || !dot[2])) {
+ doaccess = true;
+ break;
+ }
+
+ name = lsp->fullname;
}
if (doaccess && access(name, R_OK) != 0)
return errno;
@@ -437,47 +488,62 @@
if (close(fid) < 0)
return errno;
for (stored = 4; stored <= 8; stored *= 2) {
- int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
- int_fast32_t ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
- int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
- int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
- int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
- int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
- char const *p = up->buf + tzheadsize;
- if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
- && 0 < typecnt && typecnt < TZ_MAX_TYPES
- && 0 <= timecnt && timecnt < TZ_MAX_TIMES
- && 0 <= charcnt && charcnt < TZ_MAX_CHARS
- && (ttisstdcnt == typecnt || ttisstdcnt == 0)
- && (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
- return EINVAL;
- if (nread
- < (tzheadsize /* struct tzhead */
- + timecnt * stored /* ats */
+ char version = up->tzhead.tzh_version[0];
+ bool skip_datablock = stored == 4 && version;
+ int_fast32_t datablock_size;
+ int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
+ int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
+ int_fast64_t prevtr = -1;
+ int_fast32_t prevcorr;
+ int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
+ int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
+ int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
+ int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
+ char const *p = up->buf + tzheadsize;
+ /* Although tzfile(5) currently requires typecnt to be nonzero,
+ support future formats that may allow zero typecnt
+ in files that have a TZ string and no transitions. */
+ if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
+ && 0 <= typecnt && typecnt < TZ_MAX_TYPES
+ && 0 <= timecnt && timecnt < TZ_MAX_TIMES
+ && 0 <= charcnt && charcnt < TZ_MAX_CHARS
+ && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES
+ && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES))
+ return EINVAL;
+ datablock_size
+ = (timecnt * stored /* ats */
+ timecnt /* types */
+ typecnt * 6 /* ttinfos */
+ charcnt /* chars */
+ leapcnt * (stored + 4) /* lsinfos */
+ ttisstdcnt /* ttisstds */
- + ttisgmtcnt)) /* ttisgmts */
+ + ttisutcnt); /* ttisuts */
+ if (nread < tzheadsize + datablock_size)
+ return EINVAL;
+ if (skip_datablock)
+ p += datablock_size;
+ else {
+ if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0)
+ && (ttisutcnt == typecnt || ttisutcnt == 0)))
return EINVAL;
+
sp->leapcnt = leapcnt;
sp->timecnt = timecnt;
sp->typecnt = typecnt;
sp->charcnt = charcnt;
/* Read transitions, discarding those out of time_t range.
- But pretend the last transition before time_t_min
- occurred at time_t_min. */
+ But pretend the last transition before TIME_T_MIN
+ occurred at TIME_T_MIN. */
timecnt = 0;
for (i = 0; i < sp->timecnt; ++i) {
int_fast64_t at
= stored == 4 ? detzcode(p) : detzcode64(p);
- sp->types[i] = at <= time_t_max;
+ sp->types[i] = at <= TIME_T_MAX;
if (sp->types[i]) {
time_t attime
- = ((TYPE_SIGNED(time_t) ? at < time_t_min : at < 0)
- ? time_t_min : at);
+ = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0)
+ ? TIME_T_MIN : at);
if (timecnt && attime <= sp->ats[timecnt - 1]) {
if (attime < sp->ats[timecnt - 1])
return EINVAL;
@@ -500,23 +566,25 @@
sp->timecnt = timecnt;
for (i = 0; i < sp->typecnt; ++i) {
register struct ttinfo * ttisp;
- unsigned char isdst, abbrind;
+ unsigned char isdst, desigidx;
ttisp = &sp->ttis[i];
- ttisp->tt_gmtoff = detzcode(p);
+ ttisp->tt_utoff = detzcode(p);
p += 4;
isdst = *p++;
if (! (isdst < 2))
return EINVAL;
ttisp->tt_isdst = isdst;
- abbrind = *p++;
- if (! (abbrind < sp->charcnt))
+ desigidx = *p++;
+ if (! (desigidx < sp->charcnt))
return EINVAL;
- ttisp->tt_abbrind = abbrind;
+ ttisp->tt_desigidx = desigidx;
}
for (i = 0; i < sp->charcnt; ++i)
sp->chars[i] = *p++;
- sp->chars[i] = '\0'; /* ensure '\0' at end */
+ /* Ensure '\0'-terminated, and make it safe to call
+ ttunspecified later. */
+ memset(&sp->chars[i], 0, CHARS_EXTRA);
/* Read leap seconds, discarding those out of time_t range. */
leapcnt = 0;
@@ -524,16 +592,28 @@
int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
int_fast32_t corr = detzcode(p + stored);
p += stored + 4;
- if (tr <= time_t_max) {
- time_t trans
- = ((TYPE_SIGNED(time_t) ? tr < time_t_min : tr < 0)
- ? time_t_min : tr);
- if (leapcnt && trans <= sp->lsis[leapcnt - 1].ls_trans) {
- if (trans < sp->lsis[leapcnt - 1].ls_trans)
- return EINVAL;
- leapcnt--;
- }
- sp->lsis[leapcnt].ls_trans = trans;
+
+ /* Leap seconds cannot occur before the Epoch,
+ or out of order. */
+ if (tr <= prevtr)
+ return EINVAL;
+
+ /* To avoid other botches in this code, each leap second's
+ correction must differ from the previous one's by 1
+ second or less, except that the first correction can be
+ any value; these requirements are more generous than
+ RFC 8536, to allow future RFC extensions. */
+ if (! (i == 0
+ || (prevcorr < corr
+ ? corr == prevcorr + 1
+ : (corr == prevcorr
+ || corr == prevcorr - 1))))
+ return EINVAL;
+ prevtr = tr;
+ prevcorr = corr;
+
+ if (tr <= TIME_T_MAX) {
+ sp->lsis[leapcnt].ls_trans = tr;
sp->lsis[leapcnt].ls_corr = corr;
leapcnt++;
}
@@ -556,21 +636,22 @@
register struct ttinfo * ttisp;
ttisp = &sp->ttis[i];
- if (ttisgmtcnt == 0)
- ttisp->tt_ttisgmt = false;
+ if (ttisutcnt == 0)
+ ttisp->tt_ttisut = false;
else {
if (*p != true && *p != false)
return EINVAL;
- ttisp->tt_ttisgmt = *p++;
+ ttisp->tt_ttisut = *p++;
}
}
- /*
- ** If this is an old file, we're done.
- */
- if (up->tzhead.tzh_version[0] == '\0')
- break;
- nread -= p - up->buf;
- memmove(up->buf, p, nread);
+ }
+
+ nread -= p - up->buf;
+ memmove(up->buf, p, nread);
+
+ /* If this is an old file, we're done. */
+ if (!version)
+ break;
}
if (doextend && nread > 2 &&
up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
@@ -578,24 +659,23 @@
struct state *ts = &lsp->u.st;
up->buf[nread - 1] = '\0';
- if (tzparse(&up->buf[1], ts, false)
- && ts->typecnt == 2) {
+ if (tzparse(&up->buf[1], ts, sp)) {
/* Attempt to reuse existing abbreviations.
- Without this, America/Anchorage would stop
- working after 2037 when TZ_MAX_CHARS is 50, as
- sp->charcnt equals 42 (for LMT CAT CAWT CAPT AHST
+ Without this, America/Anchorage would be right on
+ the edge after 2037 when TZ_MAX_CHARS is 50, as
+ sp->charcnt equals 40 (for LMT AST AWT APT AHST
AHDT YST AKDT AKST) and ts->charcnt equals 10
(for AKST AKDT). Reusing means sp->charcnt can
- stay 42 in this example. */
+ stay 40 in this example. */
int gotabbr = 0;
int charcnt = sp->charcnt;
- for (i = 0; i < 2; i++) {
- char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
+ for (i = 0; i < ts->typecnt; i++) {
+ char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
int j;
for (j = 0; j < charcnt; j++)
if (strcmp(sp->chars + j, tsabbr) == 0) {
- ts->ttis[i].tt_abbrind = j;
+ ts->ttis[i].tt_desigidx = j;
gotabbr++;
break;
}
@@ -604,53 +684,83 @@
if (j + tsabbrlen < TZ_MAX_CHARS) {
strcpy(sp->chars + j, tsabbr);
charcnt = j + tsabbrlen + 1;
- ts->ttis[i].tt_abbrind = j;
+ ts->ttis[i].tt_desigidx = j;
gotabbr++;
}
}
}
- if (gotabbr == 2) {
+ if (gotabbr == ts->typecnt) {
sp->charcnt = charcnt;
- for (i = 0; i < ts->timecnt; i++)
- if (sp->ats[sp->timecnt - 1] < ts->ats[i])
- break;
- while (i < ts->timecnt
- && sp->timecnt < TZ_MAX_TIMES) {
- sp->ats[sp->timecnt] = ts->ats[i];
+
+ /* Ignore any trailing, no-op transitions generated
+ by zic as they don't help here and can run afoul
+ of bugs in zic 2016j or earlier. */
+ while (1 < sp->timecnt
+ && (sp->types[sp->timecnt - 1]
+ == sp->types[sp->timecnt - 2]))
+ sp->timecnt--;
+
+ for (i = 0;
+ i < ts->timecnt && sp->timecnt < TZ_MAX_TIMES;
+ i++) {
+ time_t t = ts->ats[i];
+ if (increment_overflow_time(&t, leapcorr(sp, t))
+ || (0 < sp->timecnt
+ && t <= sp->ats[sp->timecnt - 1]))
+ continue;
+ sp->ats[sp->timecnt] = t;
sp->types[sp->timecnt] = (sp->typecnt
+ ts->types[i]);
sp->timecnt++;
- i++;
}
- sp->ttis[sp->typecnt++] = ts->ttis[0];
- sp->ttis[sp->typecnt++] = ts->ttis[1];
+ for (i = 0; i < ts->typecnt; i++)
+ sp->ttis[sp->typecnt++] = ts->ttis[i];
}
}
}
+ if (sp->typecnt == 0)
+ return EINVAL;
if (sp->timecnt > 1) {
+ if (sp->ats[0] <= TIME_T_MAX - SECSPERREPEAT) {
+ time_t repeatat = sp->ats[0] + SECSPERREPEAT;
+ int repeattype = sp->types[0];
for (i = 1; i < sp->timecnt; ++i)
- if (typesequiv(sp, sp->types[i], sp->types[0]) &&
- differ_by_repeat(sp->ats[i], sp->ats[0])) {
+ if (sp->ats[i] == repeatat
+ && typesequiv(sp, sp->types[i], repeattype)) {
sp->goback = true;
break;
- }
+ }
+ }
+ if (TIME_T_MIN + SECSPERREPEAT <= sp->ats[sp->timecnt - 1]) {
+ time_t repeatat = sp->ats[sp->timecnt - 1] - SECSPERREPEAT;
+ int repeattype = sp->types[sp->timecnt - 1];
for (i = sp->timecnt - 2; i >= 0; --i)
- if (typesequiv(sp, sp->types[sp->timecnt - 1],
- sp->types[i]) &&
- differ_by_repeat(sp->ats[sp->timecnt - 1],
- sp->ats[i])) {
+ if (sp->ats[i] == repeatat
+ && typesequiv(sp, sp->types[i], repeattype)) {
sp->goahead = true;
break;
- }
+ }
+ }
}
+
+ /* Infer sp->defaulttype from the data. Although this default
+ type is always zero for data from recent tzdb releases,
+ things are trickier for data from tzdb 2018e or earlier.
+
+ The first set of heuristics work around bugs in 32-bit data
+ generated by tzdb 2013c or earlier. The workaround is for
+ zones like Australia/Macquarie where timestamps before the
+ first transition have a time type that is not the earliest
+ standard-time type. See:
+ https://mm.icann.org/pipermail/tz/2013-May/019368.html */
/*
- ** If type 0 is is unused in transitions,
+ ** If type 0 does not specify local time, or is unused in transitions,
** it's the type to use for early times.
*/
for (i = 0; i < sp->timecnt; ++i)
if (sp->types[i] == 0)
break;
- i = i < sp->timecnt ? -1 : 0;
+ i = i < sp->timecnt && ! ttunspecified(sp, 0) ? -1 : 0;
/*
** Absent the above,
** if there are transition times
@@ -664,6 +774,9 @@
if (!sp->ttis[i].tt_isdst)
break;
}
+ /* The next heuristics are for data generated by tzdb 2018e or
+ earlier, for zones like EST5EDT where the first transition
+ is to DST. */
/*
** If no result yet, find the first standard type.
** If there is none, punt to type zero.
@@ -676,7 +789,12 @@
break;
}
}
+ /* A simple 'sp->defaulttype = 0;' would suffice here if we
+ didn't have to worry about 2018e-or-earlier data. Even
+ simpler would be to remove the defaulttype member and just
+ use 0 in its place. */
sp->defaulttype = i;
+
return 0;
}
@@ -687,9 +805,9 @@
{
#ifdef ALL_STATE
union local_storage *lsp = malloc(sizeof *lsp);
- if (!lsp)
- return errno;
- else {
+ if (!lsp) {
+ return HAVE_MALLOC_ERRNO ? errno : ENOMEM;
+ } else {
int err = tzloadbody(name, sp, doextend, lsp);
free(lsp);
return err;
@@ -712,12 +830,13 @@
else {
register const struct ttinfo * ap = &sp->ttis[a];
register const struct ttinfo * bp = &sp->ttis[b];
- result = ap->tt_gmtoff == bp->tt_gmtoff &&
- ap->tt_isdst == bp->tt_isdst &&
- ap->tt_ttisstd == bp->tt_ttisstd &&
- ap->tt_ttisgmt == bp->tt_ttisgmt &&
- strcmp(&sp->chars[ap->tt_abbrind],
- &sp->chars[bp->tt_abbrind]) == 0;
+ result = (ap->tt_utoff == bp->tt_utoff
+ && ap->tt_isdst == bp->tt_isdst
+ && ap->tt_ttisstd == bp->tt_ttisstd
+ && ap->tt_ttisut == bp->tt_ttisut
+ && (strcmp(&sp->chars[ap->tt_desigidx],
+ &sp->chars[bp->tt_desigidx])
+ == 0));
}
return result;
}
@@ -731,13 +850,20 @@
DAYSPERNYEAR, DAYSPERLYEAR
};
+/* Is C an ASCII digit? */
+static bool
+is_digit(char c)
+{
+ return '0' <= c && c <= '9';
+}
+
/*
-** Given a pointer into a time zone string, scan until a character that is not
-** a valid character in a zone name is found. Return a pointer to that
-** character.
+** Given a pointer into a timezone string, scan until a character that is not
+** a valid character in a time zone abbreviation is found.
+** Return a pointer to that character.
*/
-static const char * ATTRIBUTE_PURE
+static ATTRIBUTE_PURE const char *
getzname(register const char *strp)
{
register char c;
@@ -749,15 +875,16 @@
}
/*
-** Given a pointer into an extended time zone string, scan until the ending
-** delimiter of the zone name is located. Return a pointer to the delimiter.
+** Given a pointer into an extended timezone string, scan until the ending
+** delimiter of the time zone abbreviation is located.
+** Return a pointer to the delimiter.
**
** As with getzname above, the legal character set is actually quite
** restricted, with other characters producing undefined results.
** We don't do any checking here; checking is done later in common-case code.
*/
-static const char * ATTRIBUTE_PURE
+static ATTRIBUTE_PURE const char *
getqzname(register const char *strp, const int delim)
{
register int c;
@@ -768,7 +895,7 @@
}
/*
-** Given a pointer into a time zone string, extract a number from that string.
+** Given a pointer into a timezone string, extract a number from that string.
** Check that the number is within a specified range; if it is not, return
** NULL.
** Otherwise, return a pointer to the first character not part of the number.
@@ -796,7 +923,7 @@
}
/*
-** Given a pointer into a time zone string, extract a number of seconds,
+** Given a pointer into a timezone string, extract a number of seconds,
** in hh[:mm[:ss]] form, from the string.
** If any error occurs, return NULL.
** Otherwise, return a pointer to the first character not part of the number
@@ -807,6 +934,7 @@
getsecs(register const char *strp, int_fast32_t *const secsp)
{
int num;
+ int_fast32_t secsperhour = SECSPERHOUR;
/*
** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
@@ -817,7 +945,7 @@
strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
if (strp == NULL)
return NULL;
- *secsp = num * (int_fast32_t) SECSPERHOUR;
+ *secsp = num * secsperhour;
if (*strp == ':') {
++strp;
strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
@@ -837,7 +965,7 @@
}
/*
-** Given a pointer into a time zone string, extract an offset, in
+** Given a pointer into a timezone string, extract an offset, in
** [+-]hh[:mm[:ss]] form, from the string.
** If any error occurs, return NULL.
** Otherwise, return a pointer to the first character not part of the time.
@@ -862,7 +990,7 @@
}
/*
-** Given a pointer into a time zone string, extract a rule in the form
+** Given a pointer into a timezone string, extract a rule in the form
** date[/time]. See POSIX section 8 for the format of "date" and "time".
** If a valid rule is not found, return NULL.
** Otherwise, return a pointer to the first character not part of the rule.
@@ -919,7 +1047,7 @@
** effect, calculate the year-relative time that rule takes effect.
*/
-static int_fast32_t ATTRIBUTE_PURE
+static int_fast32_t
transtime(const int year, register const struct rule *const rulep,
const int_fast32_t offset)
{
@@ -928,7 +1056,6 @@
register int i;
int d, m1, yy0, yy1, yy2, dow;
- INITIALIZE(value);
leapyear = isleap(year);
switch (rulep->r_type) {
@@ -994,6 +1121,8 @@
for (i = 0; i < rulep->r_mon - 1; ++i)
value += mon_lengths[leapyear][i] * SECSPERDAY;
break;
+
+ default: UNREACHABLE();
}
/*
@@ -1011,7 +1140,7 @@
*/
static bool
-tzparse(const char *name, struct state *sp, bool lastditch)
+tzparse(const char *name, struct state *sp, struct state *basep)
{
const char * stdname;
const char * dstname;
@@ -1022,37 +1151,42 @@
int_fast32_t dstoffset;
register char * cp;
register bool load_ok;
+ time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN;
stdname = name;
- if (lastditch) {
- stdlen = sizeof gmt - 1;
- name += stdlen;
- stdoffset = 0;
+ if (*name == '<') {
+ name++;
+ stdname = name;
+ name = getqzname(name, '>');
+ if (*name != '>')
+ return false;
+ stdlen = name - stdname;
+ name++;
} else {
- if (*name == '<') {
- name++;
- stdname = name;
- name = getqzname(name, '>');
- if (*name != '>')
- return false;
- stdlen = name - stdname;
- name++;
- } else {
- name = getzname(name);
- stdlen = name - stdname;
- }
- if (!stdlen)
- return false;
- name = getoffset(name, &stdoffset);
- if (name == NULL)
- return false;
+ name = getzname(name);
+ stdlen = name - stdname;
}
+ if (!stdlen)
+ return false;
+ name = getoffset(name, &stdoffset);
+ if (name == NULL)
+ return false;
charcnt = stdlen + 1;
if (sizeof sp->chars < charcnt)
return false;
- load_ok = tzload(TZDEFRULES, sp, false) == 0;
- if (!load_ok)
- sp->leapcnt = 0; /* so, we're off a little */
+ if (basep) {
+ if (0 < basep->timecnt)
+ atlo = basep->ats[basep->timecnt - 1];
+ load_ok = false;
+ sp->leapcnt = basep->leapcnt;
+ memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis);
+ } else {
+ load_ok = tzload(TZDEFRULES, sp, false) == 0;
+ if (!load_ok)
+ sp->leapcnt = 0; /* So, we're off a little. */
+ }
+ if (0 < sp->leapcnt)
+ leaplo = sp->lsis[sp->leapcnt - 1].ls_trans;
if (*name != '\0') {
if (*name == '<') {
dstname = ++name;
@@ -1064,7 +1198,7 @@
} else {
dstname = name;
name = getzname(name);
- dstlen = name - dstname; /* length of DST zone name */
+ dstlen = name - dstname; /* length of DST abbr. */
}
if (!dstlen)
return false;
@@ -1082,9 +1216,10 @@
struct rule start;
struct rule end;
register int year;
- register int yearlim;
register int timecnt;
time_t janfirst;
+ int_fast32_t janoffset = 0;
+ int yearbeg, yearlim;
++name;
if ((name = getrule(name, &start)) == NULL)
@@ -1099,13 +1234,41 @@
/*
** Two transitions per year, from EPOCH_YEAR forward.
*/
- init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
- init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
+ init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
+ init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
sp->defaulttype = 0;
timecnt = 0;
janfirst = 0;
- yearlim = EPOCH_YEAR + YEARSPERREPEAT;
- for (year = EPOCH_YEAR; year < yearlim; year++) {
+ yearbeg = EPOCH_YEAR;
+
+ do {
+ int_fast32_t yearsecs
+ = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
+ yearbeg--;
+ if (increment_overflow_time(&janfirst, -yearsecs)) {
+ janoffset = -yearsecs;
+ break;
+ }
+ } while (atlo < janfirst
+ && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
+
+ while (true) {
+ int_fast32_t yearsecs
+ = year_lengths[isleap(yearbeg)] * SECSPERDAY;
+ int yearbeg1 = yearbeg;
+ time_t janfirst1 = janfirst;
+ if (increment_overflow_time(&janfirst1, yearsecs)
+ || increment_overflow(&yearbeg1, 1)
+ || atlo <= janfirst1)
+ break;
+ yearbeg = yearbeg1;
+ janfirst = janfirst1;
+ }
+
+ yearlim = yearbeg;
+ if (increment_overflow(&yearlim, YEARSPERREPEAT + 1))
+ yearlim = INT_MAX;
+ for (year = yearbeg; year < yearlim; year++) {
int_fast32_t
starttime = transtime(year, &start, stdoffset),
endtime = transtime(year, &end, dstoffset);
@@ -1120,29 +1283,40 @@
}
if (reversed
|| (starttime < endtime
- && (endtime - starttime
- < (yearsecs
- + (stdoffset - dstoffset))))) {
+ && endtime - starttime < yearsecs)) {
if (TZ_MAX_TIMES - 2 < timecnt)
break;
- yearlim = year + YEARSPERREPEAT + 1;
sp->ats[timecnt] = janfirst;
- if (increment_overflow_time
- (&sp->ats[timecnt], starttime))
- break;
- sp->types[timecnt++] = reversed;
+ if (! increment_overflow_time
+ (&sp->ats[timecnt],
+ janoffset + starttime)
+ && atlo <= sp->ats[timecnt])
+ sp->types[timecnt++] = !reversed;
sp->ats[timecnt] = janfirst;
- if (increment_overflow_time
- (&sp->ats[timecnt], endtime))
- break;
- sp->types[timecnt++] = !reversed;
+ if (! increment_overflow_time
+ (&sp->ats[timecnt],
+ janoffset + endtime)
+ && atlo <= sp->ats[timecnt]) {
+ sp->types[timecnt++] = reversed;
+ }
}
- if (increment_overflow_time(&janfirst, yearsecs))
+ if (endtime < leaplo) {
+ yearlim = year;
+ if (increment_overflow(&yearlim,
+ YEARSPERREPEAT + 1))
+ yearlim = INT_MAX;
+ }
+ if (increment_overflow_time
+ (&janfirst, janoffset + yearsecs))
break;
+ janoffset = 0;
}
sp->timecnt = timecnt;
- if (!timecnt)
+ if (! timecnt) {
+ sp->ttis[0] = sp->ttis[1];
sp->typecnt = 1; /* Perpetual DST. */
+ } else if (YEARSPERREPEAT < year - yearbeg)
+ sp->goback = sp->goahead = true;
} else {
register int_fast32_t theirstdoffset;
register int_fast32_t theirdstoffset;
@@ -1161,7 +1335,7 @@
j = sp->types[i];
if (!sp->ttis[j].tt_isdst) {
theirstdoffset =
- -sp->ttis[j].tt_gmtoff;
+ - sp->ttis[j].tt_utoff;
break;
}
}
@@ -1170,7 +1344,7 @@
j = sp->types[i];
if (sp->ttis[j].tt_isdst) {
theirdstoffset =
- -sp->ttis[j].tt_gmtoff;
+ - sp->ttis[j].tt_utoff;
break;
}
}
@@ -1178,7 +1352,6 @@
** Initially we're assumed to be in standard time.
*/
isdst = false;
- theiroffset = theirstdoffset;
/*
** Now juggle transition times and types
** tracking offsets as you do.
@@ -1186,16 +1359,17 @@
for (i = 0; i < sp->timecnt; ++i) {
j = sp->types[i];
sp->types[i] = sp->ttis[j].tt_isdst;
- if (sp->ttis[j].tt_ttisgmt) {
+ if (sp->ttis[j].tt_ttisut) {
/* No adjustment to transition time */
} else {
/*
- ** If summer time is in effect, and the
- ** transition time was not specified as
- ** standard time, add the summer time
- ** offset to the transition time;
- ** otherwise, add the standard time
- ** offset to the transition time.
+ ** If daylight saving time is in
+ ** effect, and the transition time was
+ ** not specified as standard time, add
+ ** the daylight saving time offset to
+ ** the transition time; otherwise, add
+ ** the standard time offset to the
+ ** transition time.
*/
/*
** Transitions from DST to DDST
@@ -1211,7 +1385,7 @@
theirstdoffset;
}
}
- theiroffset = -sp->ttis[j].tt_gmtoff;
+ theiroffset = -sp->ttis[j].tt_utoff;
if (sp->ttis[j].tt_isdst)
theirdstoffset = theiroffset;
else theirstdoffset = theiroffset;
@@ -1247,7 +1421,7 @@
gmtload(struct state *const sp)
{
if (tzload(gmt, sp, true) != 0)
- tzparse(gmt, sp, true);
+ tzparse("GMT0", sp, NULL);
}
/* Initialize *SP to a value appropriate for the TZ setting NAME.
@@ -1270,7 +1444,7 @@
return 0;
} else {
int err = tzload(name, sp, true);
- if (err != 0 && name && name[0] != ':' && tzparse(name, sp, false))
+ if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL))
err = 0;
if (err == 0)
scrub_abbrs(sp);
@@ -1301,17 +1475,6 @@
lcl_is_set = lcl;
}
-#ifdef STD_INSPIRED
-void
-tzsetwall(void)
-{
- if (lock() != 0)
- return;
- tzsetlcl(NULL);
- unlock();
-}
-#endif
-
#if defined(__BIONIC__)
extern void tzset_unlocked(void);
#else
@@ -1361,7 +1524,8 @@
errno = err;
return NULL;
}
- }
+ } else if (!HAVE_MALLOC_ERRNO)
+ errno = ENOMEM;
return sp;
}
@@ -1391,7 +1555,7 @@
**
** If successful and SETNAME is nonzero,
** set the applicable parts of tzname, timezone and altzone;
-** however, it's OK to omit this step if the time zone is POSIX-compatible,
+** however, it's OK to omit this step if the timezone is POSIX-compatible,
** since in that case tzset should have already done this step correctly.
** SETNAME's type is intfast32_t for compatibility with gmtsub,
** but it is actually a boolean and its value should be 0 or 1.
@@ -1413,7 +1577,7 @@
}
if ((sp->goback && t < sp->ats[0]) ||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
- time_t newt = t;
+ time_t newt;
register time_t seconds;
register time_t years;
@@ -1421,11 +1585,17 @@
seconds = sp->ats[0] - t;
else seconds = t - sp->ats[sp->timecnt - 1];
--seconds;
- years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
+
+ /* Beware integer overflow, as SECONDS might
+ be close to the maximum time_t. */
+ years = seconds / SECSPERREPEAT * YEARSPERREPEAT;
seconds = years * AVGSECSPERYEAR;
+ years += YEARSPERREPEAT;
if (t < sp->ats[0])
- newt += seconds;
- else newt -= seconds;
+ newt = t + seconds + SECSPERREPEAT;
+ else
+ newt = t - seconds - SECSPERREPEAT;
+
if (newt < sp->ats[0] ||
newt > sp->ats[sp->timecnt - 1])
return NULL; /* "cannot happen" */
@@ -1456,20 +1626,20 @@
hi = mid;
else lo = mid + 1;
}
- i = (int) sp->types[lo - 1];
+ i = sp->types[lo - 1];
}
ttisp = &sp->ttis[i];
/*
** To get (wrong) behavior that's compatible with System V Release 2.0
** you'd replace the statement below with
- ** t += ttisp->tt_gmtoff;
+ ** t += ttisp->tt_utoff;
** timesub(&t, 0L, sp, tmp);
*/
- result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
+ result = timesub(&t, ttisp->tt_utoff, sp, tmp);
if (result) {
result->tm_isdst = ttisp->tt_isdst;
#ifdef TM_ZONE
- result->TM_ZONE = (char *) &sp->chars[ttisp->tt_abbrind];
+ result->TM_ZONE = (char *) &sp->chars[ttisp->tt_desigidx];
#endif /* defined TM_ZONE */
if (setname)
update_tzname_etc(sp, ttisp);
@@ -1534,7 +1704,7 @@
#ifdef TM_ZONE
/*
** Could get fancy here and deliver something such as
- ** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
+ ** "+xx" or "-xx" if offset is non-zero,
** but this is no time for a treasure hunt.
*/
tmp->TM_ZONE = ((char *)
@@ -1576,11 +1746,18 @@
** where, to make the math easy, the answer for year zero is defined as zero.
*/
-static int ATTRIBUTE_PURE
-leaps_thru_end_of(register const int y)
+static time_t
+leaps_thru_end_of_nonneg(time_t y)
{
- return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
- -(leaps_thru_end_of(-(y + 1)) + 1);
+ return y / 4 - y / 100 + y / 400;
+}
+
+static time_t
+leaps_thru_end_of(time_t y)
+{
+ return (y < 0
+ ? -1 - leaps_thru_end_of_nonneg(-1 - y)
+ : leaps_thru_end_of_nonneg(y));
}
static struct tm *
@@ -1589,122 +1766,106 @@
{
register const struct lsinfo * lp;
register time_t tdays;
- register int idays; /* unsigned would be so 2003 */
- register int_fast64_t rem;
- int y;
register const int * ip;
- register int_fast64_t corr;
- register bool hit;
+ register int_fast32_t corr;
register int i;
+ int_fast32_t idays, rem, dayoff, dayrem;
+ time_t y;
+
+ /* If less than SECSPERMIN, the number of seconds since the
+ most recent positive leap second; otherwise, do not add 1
+ to localtime tm_sec because of leap seconds. */
+ time_t secs_since_posleap = SECSPERMIN;
corr = 0;
- hit = false;
i = (sp == NULL) ? 0 : sp->leapcnt;
while (--i >= 0) {
lp = &sp->lsis[i];
if (*timep >= lp->ls_trans) {
- if (*timep == lp->ls_trans) {
- hit = ((i == 0 && lp->ls_corr > 0) ||
- lp->ls_corr > sp->lsis[i - 1].ls_corr);
- if (hit)
- while (i > 0 &&
- sp->lsis[i].ls_trans ==
- sp->lsis[i - 1].ls_trans + 1 &&
- sp->lsis[i].ls_corr ==
- sp->lsis[i - 1].ls_corr + 1) {
- ++hit;
- --i;
- }
- }
corr = lp->ls_corr;
+ if ((i == 0 ? 0 : lp[-1].ls_corr) < corr)
+ secs_since_posleap = *timep - lp->ls_trans;
break;
}
}
- y = EPOCH_YEAR;
+
+ /* Calculate the year, avoiding integer overflow even if
+ time_t is unsigned. */
tdays = *timep / SECSPERDAY;
rem = *timep % SECSPERDAY;
- while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
- int newy;
- register time_t tdelta;
- register int idelta;
+ rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY;
+ dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3;
+ rem %= SECSPERDAY;
+ /* y = (EPOCH_YEAR
+ + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT),
+ sans overflow. But calculate against 1570 (EPOCH_YEAR -
+ YEARSPERREPEAT) instead of against 1970 so that things work
+ for localtime values before 1970 when time_t is unsigned. */
+ dayrem = tdays % DAYSPERREPEAT;
+ dayrem += dayoff % DAYSPERREPEAT;
+ y = (EPOCH_YEAR - YEARSPERREPEAT
+ + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT
+ - ((dayrem % DAYSPERREPEAT) < 0)
+ + tdays / DAYSPERREPEAT)
+ * YEARSPERREPEAT));
+ /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */
+ idays = tdays % DAYSPERREPEAT;
+ idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT;
+ idays %= DAYSPERREPEAT;
+ /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */
+ while (year_lengths[isleap(y)] <= idays) {
+ int tdelta = idays / DAYSPERLYEAR;
+ int_fast32_t ydelta = tdelta + !tdelta;
+ time_t newy = y + ydelta;
register int leapdays;
-
- tdelta = tdays / DAYSPERLYEAR;
- if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
- && tdelta <= INT_MAX))
- goto out_of_range;
- idelta = tdelta;
- if (idelta == 0)
- idelta = (tdays < 0) ? -1 : 1;
- newy = y;
- if (increment_overflow(&newy, idelta))
- goto out_of_range;
leapdays = leaps_thru_end_of(newy - 1) -
leaps_thru_end_of(y - 1);
- tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
- tdays -= leapdays;
+ idays -= ydelta * DAYSPERNYEAR;
+ idays -= leapdays;
y = newy;
}
- /*
- ** Given the range, we can now fearlessly cast...
- */
- idays = tdays;
- rem += offset - corr;
- while (rem < 0) {
- rem += SECSPERDAY;
- --idays;
+
+ if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) {
+ int signed_y = y;
+ tmp->tm_year = signed_y - TM_YEAR_BASE;
+ } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y)
+ && y - TM_YEAR_BASE <= INT_MAX)
+ tmp->tm_year = y - TM_YEAR_BASE;
+ else {
+ errno = EOVERFLOW;
+ return NULL;
}
- while (rem >= SECSPERDAY) {
- rem -= SECSPERDAY;
- ++idays;
- }
- while (idays < 0) {
- if (increment_overflow(&y, -1))
- goto out_of_range;
- idays += year_lengths[isleap(y)];
- }
- while (idays >= year_lengths[isleap(y)]) {
- idays -= year_lengths[isleap(y)];
- if (increment_overflow(&y, 1))
- goto out_of_range;
- }
- tmp->tm_year = y;
- if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
- goto out_of_range;
tmp->tm_yday = idays;
/*
** The "extra" mods below avoid overflow problems.
*/
- tmp->tm_wday = EPOCH_WDAY +
- ((y - EPOCH_YEAR) % DAYSPERWEEK) *
- (DAYSPERNYEAR % DAYSPERWEEK) +
- leaps_thru_end_of(y - 1) -
- leaps_thru_end_of(EPOCH_YEAR - 1) +
- idays;
+ tmp->tm_wday = (TM_WDAY_BASE
+ + ((tmp->tm_year % DAYSPERWEEK)
+ * (DAYSPERNYEAR % DAYSPERWEEK))
+ + leaps_thru_end_of(y - 1)
+ - leaps_thru_end_of(TM_YEAR_BASE - 1)
+ + idays);
tmp->tm_wday %= DAYSPERWEEK;
if (tmp->tm_wday < 0)
tmp->tm_wday += DAYSPERWEEK;
- tmp->tm_hour = (int) (rem / SECSPERHOUR);
+ tmp->tm_hour = rem / SECSPERHOUR;
rem %= SECSPERHOUR;
- tmp->tm_min = (int) (rem / SECSPERMIN);
- /*
- ** A positive leap second requires a special
- ** representation. This uses "... ??:59:60" et seq.
- */
- tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
+ tmp->tm_min = rem / SECSPERMIN;
+ tmp->tm_sec = rem % SECSPERMIN;
+
+ /* Use "... ??:??:60" at the end of the localtime minute containing
+ the second just before the positive leap second. */
+ tmp->tm_sec += secs_since_posleap <= tmp->tm_sec;
+
ip = mon_lengths[isleap(y)];
for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
idays -= ip[tmp->tm_mon];
- tmp->tm_mday = (int) (idays + 1);
+ tmp->tm_mday = idays + 1;
tmp->tm_isdst = 0;
#ifdef TM_GMTOFF
tmp->TM_GMTOFF = offset;
#endif /* defined TM_GMTOFF */
return tmp;
-
- out_of_range:
- errno = EOVERFLOW;
- return NULL;
}
char *
@@ -1778,12 +1939,12 @@
{
/*
** This is like
- ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
+ ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
** except that it does the right thing even if *tp + j would overflow.
*/
if (! (j < 0
- ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
- : *tp <= time_t_max - j))
+ ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
+ : *tp <= TIME_T_MAX - j))
return true;
*tp += j;
return false;
@@ -1919,8 +2080,8 @@
/*
** Do a binary search (this works whatever time_t's type is).
*/
- lo = time_t_min;
- hi = time_t_max;
+ lo = TIME_T_MIN;
+ hi = TIME_T_MAX;
for ( ; ; ) {
t = lo / 2 + hi / 2;
if (t < lo)
@@ -1937,12 +2098,12 @@
} else dir = tmcomp(&mytm, &yourtm);
if (dir != 0) {
if (t == lo) {
- if (t == time_t_max)
+ if (t == TIME_T_MAX)
return WRONG;
++t;
++lo;
} else if (t == hi) {
- if (t == time_t_min)
+ if (t == TIME_T_MIN)
return WRONG;
--t;
--hi;
@@ -1959,13 +2120,13 @@
&& (yourtm.TM_GMTOFF < 0
? (-SECSPERDAY <= yourtm.TM_GMTOFF
&& (mytm.TM_GMTOFF <=
- (SMALLEST (INT_FAST32_MAX, LONG_MAX)
+ (SMALLEST(INT_FAST32_MAX, LONG_MAX)
+ yourtm.TM_GMTOFF)))
: (yourtm.TM_GMTOFF <= SECSPERDAY
- && ((BIGGEST (INT_FAST32_MIN, LONG_MIN)
+ && ((BIGGEST(INT_FAST32_MIN, LONG_MIN)
+ yourtm.TM_GMTOFF)
<= mytm.TM_GMTOFF)))) {
- /* MYTM matches YOURTM except with the wrong UTC offset.
+ /* MYTM matches YOURTM except with the wrong UT offset.
YOURTM.TM_GMTOFF is plausible, so try it instead.
It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
since the guess gets checked. */
@@ -1999,8 +2160,10 @@
for (j = sp->typecnt - 1; j >= 0; --j) {
if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
continue;
- newt = t + sp->ttis[j].tt_gmtoff -
- sp->ttis[i].tt_gmtoff;
+ if (ttunspecified(sp, j))
+ continue;
+ newt = (t + sp->ttis[j].tt_utoff
+ - sp->ttis[i].tt_utoff);
if (! funcp(sp, &newt, offset, &mytm))
continue;
if (tmcomp(&mytm, &yourtm) != 0)
@@ -2047,8 +2210,8 @@
static time_t
time1(struct tm *const tmp,
- struct tm *(*funcp) (struct state const *, time_t const *,
- int_fast32_t, struct tm *),
+ struct tm *(*funcp)(struct state const *, time_t const *,
+ int_fast32_t, struct tm *),
struct state const *sp,
const int_fast32_t offset)
{
@@ -2091,7 +2254,7 @@
seen[i] = false;
nseen = 0;
for (i = sp->timecnt - 1; i >= 0; --i)
- if (!seen[sp->types[i]]) {
+ if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) {
seen[sp->types[i]] = true;
types[nseen++] = sp->types[i];
}
@@ -2103,14 +2266,14 @@
otheri = types[otherind];
if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
continue;
- tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
- sp->ttis[samei].tt_gmtoff;
+ tmp->tm_sec += (sp->ttis[otheri].tt_utoff
+ - sp->ttis[samei].tt_utoff);
tmp->tm_isdst = !tmp->tm_isdst;
t = time2(tmp, funcp, sp, offset, &okay);
if (okay)
return t;
- tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
- sp->ttis[samei].tt_gmtoff;
+ tmp->tm_sec -= (sp->ttis[otheri].tt_utoff
+ - sp->ttis[samei].tt_utoff);
tmp->tm_isdst = !tmp->tm_isdst;
}
}
@@ -2188,21 +2351,7 @@
#endif /* defined STD_INSPIRED */
-/*
-** XXX--is the below the right way to conditionalize??
-*/
-
-#ifdef STD_INSPIRED
-
-/*
-** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
-** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
-** is not the case if we are accounting for leap seconds.
-** So, we provide the following conversion routines for use
-** when exchanging timestamps with POSIX conforming systems.
-*/
-
-static int_fast64_t
+static int_fast32_t
leapcorr(struct state const *sp, time_t t)
{
register struct lsinfo const * lp;
@@ -2217,7 +2366,29 @@
return 0;
}
-NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
+/*
+** XXX--is the below the right way to conditionalize??
+*/
+
+#ifdef STD_INSPIRED
+
+/* NETBSD_INSPIRED_EXTERN functions are exported to callers if
+ NETBSD_INSPIRED is defined, and are private otherwise. */
+# if NETBSD_INSPIRED
+# define NETBSD_INSPIRED_EXTERN
+# else
+# define NETBSD_INSPIRED_EXTERN static
+# endif
+
+/*
+** IEEE Std 1003.1 (POSIX) says that 536457599
+** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
+** is not the case if we are accounting for leap seconds.
+** So, we provide the following conversion routines for use
+** when exchanging timestamps with POSIX conforming systems.
+*/
+
+NETBSD_INSPIRED_EXTERN time_t
time2posix_z(struct state *sp, time_t t)
{
return t - leapcorr(sp, t);
@@ -2239,7 +2410,7 @@
return t;
}
-NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
+NETBSD_INSPIRED_EXTERN time_t
posix2time_z(struct state *sp, time_t t)
{
time_t x;
@@ -2286,15 +2457,39 @@
#endif /* defined STD_INSPIRED */
-#ifdef time_tz
+#if TZ_TIME_T
+
+# if !USG_COMPAT
+# define daylight 0
+# define timezone 0
+# endif
+# if !ALTZONE
+# define altzone 0
+# endif
/* Convert from the underlying system's time_t to the ersatz time_tz,
- which is called 'time_t' in this file. */
+ which is called 'time_t' in this file. Typically, this merely
+ converts the time's integer width. On some platforms, the system
+ time is local time not UT, or uses some epoch other than the POSIX
+ epoch.
+
+ Although this code appears to define a function named 'time' that
+ returns time_t, the macros in private.h cause this code to actually
+ define a function named 'tz_time' that returns tz_time_t. The call
+ to sys_time invokes the underlying system's 'time' function. */
time_t
time(time_t *p)
{
time_t r = sys_time(0);
+ if (r != (time_t) -1) {
+ int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0;
+ if (increment_overflow32(&offset, -EPOCH_OFFSET)
+ || increment_overflow_time(&r, offset)) {
+ errno = EOVERFLOW;
+ r = -1;
+ }
+ }
if (p)
*p = r;
return r;
diff --git a/libc/tzcode/private.h b/libc/tzcode/private.h
index 941e91b..4c03324 100644
--- a/libc/tzcode/private.h
+++ b/libc/tzcode/private.h
@@ -1,3 +1,5 @@
+/* Private header for tzdb code. */
+
#ifndef PRIVATE_H
#define PRIVATE_H
@@ -15,6 +17,17 @@
** Thank you!
*/
+/*
+** zdump has been made independent of the rest of the time
+** conversion package to increase confidence in the verification it provides.
+** You can use zdump to help in verifying other implementations.
+** To do this, compile with -DUSE_LTZ=0 and link without the tz library.
+*/
+#ifndef USE_LTZ
+# define USE_LTZ 1
+#endif
+
+/* This string was in the Factory zone through version 2016f. */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
/*
@@ -26,26 +39,53 @@
#define HAVE_DECL_ASCTIME_R 1
#endif
+#if !defined HAVE_GENERIC && defined __has_extension
+# if __has_extension(c_generic_selections)
+# define HAVE_GENERIC 1
+# else
+# define HAVE_GENERIC 0
+# endif
+#endif
+/* _Generic is buggy in pre-4.9 GCC. */
+#if !defined HAVE_GENERIC && defined __GNUC__
+# define HAVE_GENERIC (4 < __GNUC__ + (9 <= __GNUC_MINOR__))
+#endif
+#ifndef HAVE_GENERIC
+# define HAVE_GENERIC (201112 <= __STDC_VERSION__)
+#endif
+
#ifndef HAVE_GETTEXT
#define HAVE_GETTEXT 0
#endif /* !defined HAVE_GETTEXT */
#ifndef HAVE_INCOMPATIBLE_CTIME_R
#define HAVE_INCOMPATIBLE_CTIME_R 0
-#endif /* !defined INCOMPATIBLE_CTIME_R */
+#endif
#ifndef HAVE_LINK
#define HAVE_LINK 1
#endif /* !defined HAVE_LINK */
+#ifndef HAVE_MALLOC_ERRNO
+#define HAVE_MALLOC_ERRNO 1
+#endif
+
#ifndef HAVE_POSIX_DECLS
#define HAVE_POSIX_DECLS 1
#endif
+#ifndef HAVE_STDBOOL_H
+#define HAVE_STDBOOL_H (199901 <= __STDC_VERSION__)
+#endif
+
#ifndef HAVE_STRDUP
#define HAVE_STRDUP 1
#endif
+#ifndef HAVE_STRTOLL
+#define HAVE_STRTOLL 1
+#endif
+
#ifndef HAVE_SYMLINK
#define HAVE_SYMLINK 1
#endif /* !defined HAVE_SYMLINK */
@@ -54,10 +94,6 @@
#define HAVE_SYS_STAT_H 1
#endif /* !defined HAVE_SYS_STAT_H */
-#ifndef HAVE_SYS_WAIT_H
-#define HAVE_SYS_WAIT_H 1
-#endif /* !defined HAVE_SYS_WAIT_H */
-
#ifndef HAVE_UNISTD_H
#define HAVE_UNISTD_H 1
#endif /* !defined HAVE_UNISTD_H */
@@ -75,22 +111,37 @@
#define ctime_r _incompatible_ctime_r
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
-/* Enable tm_gmtoff and tm_zone on GNUish systems. */
+/* Enable tm_gmtoff, tm_zone, and environ on GNUish systems. */
#define _GNU_SOURCE 1
-/* Fix asctime_r on Solaris 10. */
+/* Fix asctime_r on Solaris 11. */
#define _POSIX_PTHREAD_SEMANTICS 1
-/* Enable strtoimax on Solaris 10. */
+/* Enable strtoimax on pre-C99 Solaris 11. */
#define __EXTENSIONS__ 1
+/* To avoid having 'stat' fail unnecessarily with errno == EOVERFLOW,
+ enable large files on GNUish systems ... */
+#ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+#endif
+/* ... and on AIX ... */
+#define _LARGE_FILES 1
+/* ... and enable large inode numbers on Mac OS X 10.5 and later. */
+#define _DARWIN_USE_64_BIT_INODE 1
+
/*
** Nested includes
*/
-/* Avoid clashes with NetBSD by renaming NetBSD's declarations. */
+/* Avoid clashes with NetBSD by renaming NetBSD's declarations.
+ If defining the 'timezone' variable, avoid a clash with FreeBSD's
+ 'timezone' function by renaming its declaration. */
#define localtime_rz sys_localtime_rz
#define mktime_z sys_mktime_z
#define posix2time_z sys_posix2time_z
#define time2posix_z sys_time2posix_z
+#if defined USG_COMPAT && USG_COMPAT == 2
+# define timezone sys_timezone
+#endif
#define timezone_t sys_timezone_t
#define tzalloc sys_tzalloc
#define tzfree sys_tzfree
@@ -99,21 +150,30 @@
#undef mktime_z
#undef posix2time_z
#undef time2posix_z
+#if defined USG_COMPAT && USG_COMPAT == 2
+# undef timezone
+#endif
#undef timezone_t
#undef tzalloc
#undef tzfree
-#include "sys/types.h" /* for time_t */
-#include "stdio.h"
-#include "string.h"
-#include "limits.h" /* for CHAR_BIT et al. */
-#include "stdlib.h"
+#include <sys/types.h> /* for time_t */
+#include <string.h>
+#include <limits.h> /* for CHAR_BIT et al. */
+#include <stdlib.h>
-#include "errno.h"
+#include <errno.h>
+
+#ifndef EINVAL
+# define EINVAL ERANGE
+#endif
#ifndef ENAMETOOLONG
# define ENAMETOOLONG EINVAL
#endif
+#ifndef ENOMEM
+# define ENOMEM EINVAL
+#endif
#ifndef ENOTSUP
# define ENOTSUP EINVAL
#endif
@@ -122,22 +182,11 @@
#endif
#if HAVE_GETTEXT
-#include "libintl.h"
+#include <libintl.h>
#endif /* HAVE_GETTEXT */
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
-#endif /* HAVE_SYS_WAIT_H */
-
-#ifndef WIFEXITED
-#define WIFEXITED(status) (((status) & 0xff) == 0)
-#endif /* !defined WIFEXITED */
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
-#endif /* !defined WEXITSTATUS */
-
#if HAVE_UNISTD_H
-#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */
+#include <unistd.h> /* for R_OK, and other POSIX goodness */
#endif /* HAVE_UNISTD_H */
#ifndef HAVE_STRFTIME_L
@@ -148,31 +197,49 @@
# endif
#endif
-#ifndef F_OK
-#define F_OK 0
-#endif /* !defined F_OK */
+#ifndef USG_COMPAT
+# ifndef _XOPEN_VERSION
+# define USG_COMPAT 0
+# else
+# define USG_COMPAT 1
+# endif
+#endif
+
+#ifndef HAVE_TZNAME
+# if _POSIX_VERSION < 198808 && !USG_COMPAT
+# define HAVE_TZNAME 0
+# else
+# define HAVE_TZNAME 1
+# endif
+#endif
+
+#ifndef ALTZONE
+# if defined __sun || defined _M_XENIX
+# define ALTZONE 1
+# else
+# define ALTZONE 0
+# endif
+#endif
+
#ifndef R_OK
#define R_OK 4
#endif /* !defined R_OK */
-/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
-#define is_digit(c) ((unsigned)(c) - '0' <= 9)
-
/*
** Define HAVE_STDINT_H's default value here, rather than at the
-** start, since __GLIBC__'s value depends on previously-included
-** files.
-** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
+** start, since __GLIBC__ and INTMAX_MAX's values depend on
+** previously-included files. glibc 2.1 and Solaris 10 and later have
+** stdint.h, even with pre-C99 compilers.
*/
#ifndef HAVE_STDINT_H
#define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ \
|| 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
- || __CYGWIN__)
+ || __CYGWIN__ || INTMAX_MAX)
#endif /* !defined HAVE_STDINT_H */
#if HAVE_STDINT_H
-#include "stdint.h"
+#include <stdint.h>
#endif /* !HAVE_STDINT_H */
#ifndef HAVE_INTTYPES_H
@@ -208,14 +275,18 @@
# endif
#endif
-#ifndef SCNdFAST64
+#ifndef PRIdFAST64
# if INT_FAST64_MAX == LLONG_MAX
-# define SCNdFAST64 "lld"
+# define PRIdFAST64 "lld"
# else
-# define SCNdFAST64 "ld"
+# define PRIdFAST64 "ld"
# endif
#endif
+#ifndef SCNdFAST64
+# define SCNdFAST64 PRIdFAST64
+#endif
+
#ifndef INT_FAST32_MAX
# if INT_MAX >> 31 == 0
typedef long int_fast32_t;
@@ -231,15 +302,19 @@
#ifndef INTMAX_MAX
# ifdef LLONG_MAX
typedef long long intmax_t;
-# define strtoimax strtoll
+# if HAVE_STRTOLL
+# define strtoimax strtoll
+# endif
# define INTMAX_MAX LLONG_MAX
# define INTMAX_MIN LLONG_MIN
# else
typedef long intmax_t;
-# define strtoimax strtol
# define INTMAX_MAX LONG_MAX
# define INTMAX_MIN LONG_MIN
# endif
+# ifndef strtoimax
+# define strtoimax strtol
+# endif
#endif
#ifndef PRIdMAX
@@ -250,6 +325,10 @@
# endif
#endif
+#ifndef UINT_FAST32_MAX
+typedef unsigned long uint_fast32_t;
+#endif
+
#ifndef UINT_FAST64_MAX
# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
typedef unsigned long long uint_fast64_t;
@@ -289,19 +368,21 @@
#define SIZE_MAX ((size_t) -1)
#endif
-#if 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
-# define ATTRIBUTE_CONST __attribute__ ((const))
-# define ATTRIBUTE_PURE __attribute__ ((__pure__))
-# define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
+#if 3 <= __GNUC__
+# define ATTRIBUTE_CONST __attribute__((const))
+# define ATTRIBUTE_MALLOC __attribute__((__malloc__))
+# define ATTRIBUTE_PURE __attribute__((__pure__))
+# define ATTRIBUTE_FORMAT(spec) __attribute__((__format__ spec))
#else
# define ATTRIBUTE_CONST /* empty */
+# define ATTRIBUTE_MALLOC /* empty */
# define ATTRIBUTE_PURE /* empty */
# define ATTRIBUTE_FORMAT(spec) /* empty */
#endif
#if !defined _Noreturn && __STDC_VERSION__ < 201112
# if 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
-# define _Noreturn __attribute__ ((__noreturn__))
+# define _Noreturn __attribute__((__noreturn__))
# else
# define _Noreturn
# endif
@@ -315,6 +396,23 @@
** Workarounds for compilers/systems.
*/
+#ifndef EPOCH_LOCAL
+# define EPOCH_LOCAL 0
+#endif
+#ifndef EPOCH_OFFSET
+# define EPOCH_OFFSET 0
+#endif
+#ifndef RESERVE_STD_EXT_IDS
+# define RESERVE_STD_EXT_IDS 0
+#endif
+
+/* If standard C identifiers with external linkage (e.g., localtime)
+ are reserved and are not already being renamed anyway, rename them
+ as if compiling with '-Dtime_tz=time_t'. */
+#if !defined time_tz && RESERVE_STD_EXT_IDS && USE_LTZ
+# define time_tz time_t
+#endif
+
/*
** Compile with -Dtime_tz=T to build the tz package with a private
** time_t type equivalent to T rather than the system-supplied time_t.
@@ -322,13 +420,24 @@
** (e.g., time_t wider than 'long', or unsigned time_t) even on
** typical platforms.
*/
-#ifdef time_tz
-# ifdef LOCALTIME_IMPLEMENTATION
+#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
+# define TZ_TIME_T 1
+#else
+# define TZ_TIME_T 0
+#endif
+
+#if defined LOCALTIME_IMPLEMENTATION && TZ_TIME_T
static time_t sys_time(time_t *x) { return time(x); }
-# endif
+#endif
+
+#if TZ_TIME_T
typedef time_tz tz_time_t;
+# undef asctime
+# define asctime tz_asctime
+# undef asctime_r
+# define asctime_r tz_asctime_r
# undef ctime
# define ctime tz_ctime
# undef ctime_r
@@ -355,6 +464,8 @@
# define posix2time tz_posix2time
# undef posix2time_z
# define posix2time_z tz_posix2time_z
+# undef strftime
+# define strftime tz_strftime
# undef time
# define time tz_time
# undef time2posix
@@ -375,12 +486,36 @@
# define tzfree tz_tzfree
# undef tzset
# define tzset tz_tzset
-# undef tzsetwall
-# define tzsetwall tz_tzsetwall
+# if HAVE_STRFTIME_L
+# undef strftime_l
+# define strftime_l tz_strftime_l
+# endif
+# if HAVE_TZNAME
+# undef tzname
+# define tzname tz_tzname
+# endif
+# if USG_COMPAT
+# undef daylight
+# define daylight tz_daylight
+# undef timezone
+# define timezone tz_timezone
+# endif
+# if ALTZONE
+# undef altzone
+# define altzone tz_altzone
+# endif
+char *asctime(struct tm const *);
+char *asctime_r(struct tm const *restrict, char *restrict);
char *ctime(time_t const *);
char *ctime_r(time_t const *, char *);
-double difftime(time_t, time_t);
+double difftime(time_t, time_t) ATTRIBUTE_CONST;
+size_t strftime(char *restrict, size_t, char const *restrict,
+ struct tm const *restrict);
+# if HAVE_STRFTIME_L
+size_t strftime_l(char *restrict, size_t, char const *restrict,
+ struct tm const *restrict, locale_t);
+# endif
struct tm *gmtime(time_t const *);
struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
struct tm *localtime(time_t const *);
@@ -394,18 +529,26 @@
extern char *asctime_r(struct tm const *restrict, char *restrict);
#endif
-#if !HAVE_POSIX_DECLS
-# ifdef USG_COMPAT
-# ifndef timezone
-extern long timezone;
-# endif
-# ifndef daylight
-extern int daylight;
-# endif
+#ifndef HAVE_DECL_ENVIRON
+# if defined environ || defined __USE_GNU
+# define HAVE_DECL_ENVIRON 1
+# else
+# define HAVE_DECL_ENVIRON 0
# endif
#endif
-#if defined ALTZONE && !defined altzone
+#if !HAVE_DECL_ENVIRON
+extern char **environ;
+#endif
+
+#if 2 <= HAVE_TZNAME + (TZ_TIME_T || !HAVE_POSIX_DECLS)
+extern char *tzname[];
+#endif
+#if 2 <= USG_COMPAT + (TZ_TIME_T || !HAVE_POSIX_DECLS)
+extern long timezone;
+extern int daylight;
+#endif
+#if 2 <= ALTZONE + (TZ_TIME_T || !HAVE_POSIX_DECLS)
extern long altzone;
#endif
@@ -415,25 +558,22 @@
*/
#ifdef STD_INSPIRED
-# if !defined tzsetwall || defined time_tz
-void tzsetwall(void);
-# endif
-# if !defined offtime || defined time_tz
+# if TZ_TIME_T || !defined offtime
struct tm *offtime(time_t const *, long);
# endif
-# if !defined timegm || defined time_tz
+# if TZ_TIME_T || !defined timegm
time_t timegm(struct tm *);
# endif
-# if !defined timelocal || defined time_tz
+# if TZ_TIME_T || !defined timelocal
time_t timelocal(struct tm *);
# endif
-# if !defined timeoff || defined time_tz
+# if TZ_TIME_T || !defined timeoff
time_t timeoff(struct tm *, long);
# endif
-# if !defined time2posix || defined time_tz
+# if TZ_TIME_T || !defined time2posix
time_t time2posix(time_t);
# endif
-# if !defined posix2time || defined time_tz
+# if TZ_TIME_T || !defined posix2time
time_t posix2time(time_t);
# endif
#endif
@@ -467,10 +607,10 @@
timezone_t tzalloc(char const *);
void tzfree(timezone_t);
# ifdef STD_INSPIRED
-# if !defined posix2time_z || defined time_tz
+# if TZ_TIME_T || !defined posix2time_z
time_t posix2time_z(timezone_t, time_t) ATTRIBUTE_PURE;
# endif
-# if !defined time2posix_z || defined time_tz
+# if TZ_TIME_T || !defined time2posix_z
time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
# endif
# endif
@@ -480,22 +620,16 @@
** Finally, some convenience items.
*/
-#if __STDC_VERSION__ < 199901
+#if HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
# define true 1
# define false 0
# define bool int
-#else
-# include <stdbool.h>
#endif
-#ifndef TYPE_BIT
-#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
-#endif /* !defined TYPE_BIT */
-
-#ifndef TYPE_SIGNED
+#define TYPE_BIT(type) (sizeof(type) * CHAR_BIT)
#define TYPE_SIGNED(type) (((type) -1) < 0)
-#endif /* !defined TYPE_SIGNED */
-
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
/* Max and min values of the integer type T, of which only the bottom
@@ -507,11 +641,34 @@
#define MINVAL(t, b) \
((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
-/* The minimum and maximum finite time values. This assumes no padding. */
-static time_t const time_t_min = MINVAL(time_t, TYPE_BIT(time_t));
-static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
+/* The extreme time values, assuming no padding. */
+#define TIME_T_MIN_NO_PADDING MINVAL(time_t, TYPE_BIT(time_t))
+#define TIME_T_MAX_NO_PADDING MAXVAL(time_t, TYPE_BIT(time_t))
-#ifndef INT_STRLEN_MAXIMUM
+/* The extreme time values. These are macros, not constants, so that
+ any portability problems occur only when compiling .c files that use
+ the macros, which is safer for applications that need only zdump and zic.
+ This implementation assumes no padding if time_t is signed and
+ either the compiler lacks support for _Generic or time_t is not one
+ of the standard signed integer types. */
+#if HAVE_GENERIC
+# define TIME_T_MIN \
+ _Generic((time_t) 0, \
+ signed char: SCHAR_MIN, short: SHRT_MIN, \
+ int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN, \
+ default: TIME_T_MIN_NO_PADDING)
+# define TIME_T_MAX \
+ (TYPE_SIGNED(time_t) \
+ ? _Generic((time_t) 0, \
+ signed char: SCHAR_MAX, short: SHRT_MAX, \
+ int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX, \
+ default: TIME_T_MAX_NO_PADDING) \
+ : (time_t) -1)
+#else
+# define TIME_T_MIN TIME_T_MIN_NO_PADDING
+# define TIME_T_MAX TIME_T_MAX_NO_PADDING
+#endif
+
/*
** 302 / 1000 is log10(2.0) rounded up.
** Subtract one for the sign bit if the type is signed;
@@ -521,13 +678,12 @@
#define INT_STRLEN_MAXIMUM(type) \
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
1 + TYPE_SIGNED(type))
-#endif /* !defined INT_STRLEN_MAXIMUM */
/*
** INITIALIZE(x)
*/
-#ifdef lint
+#ifdef GCC_LINT
# define INITIALIZE(x) ((x) = 0)
#else
# define INITIALIZE(x)
@@ -537,19 +693,30 @@
# define UNINIT_TRAP 0
#endif
+#ifdef DEBUG
+# define UNREACHABLE() abort()
+#elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
+# define UNREACHABLE() __builtin_unreachable()
+#elif defined __has_builtin
+# if __has_builtin(__builtin_unreachable)
+# define UNREACHABLE() __builtin_unreachable()
+# endif
+#endif
+#ifndef UNREACHABLE
+# define UNREACHABLE() ((void) 0)
+#endif
+
/*
** For the benefit of GNU folk...
** '_(MSGID)' uses the current locale's message library string for MSGID.
** The default is to use gettext if available, and use MSGID otherwise.
*/
-#ifndef _
#if HAVE_GETTEXT
#define _(msgid) gettext(msgid)
#else /* !HAVE_GETTEXT */
#define _(msgid) msgid
#endif /* !HAVE_GETTEXT */
-#endif /* !defined _ */
#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
# define TZ_DOMAIN "tz"
@@ -562,24 +729,64 @@
char *ctime_r(time_t const *, char *);
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
-#ifndef YEARSPERREPEAT
+/* Handy macros that are independent of tzfile implementation. */
+
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+#define DAYSPERWEEK 7
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR 12
+
#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
-#endif /* !defined YEARSPERREPEAT */
+#define DAYSPERREPEAT ((int_fast32_t) 400 * 365 + 100 - 4 + 1)
+#define SECSPERREPEAT ((int_fast64_t) DAYSPERREPEAT * SECSPERDAY)
+#define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT)
+
+#define TM_SUNDAY 0
+#define TM_MONDAY 1
+#define TM_TUESDAY 2
+#define TM_WEDNESDAY 3
+#define TM_THURSDAY 4
+#define TM_FRIDAY 5
+#define TM_SATURDAY 6
+
+#define TM_JANUARY 0
+#define TM_FEBRUARY 1
+#define TM_MARCH 2
+#define TM_APRIL 3
+#define TM_MAY 4
+#define TM_JUNE 5
+#define TM_JULY 6
+#define TM_AUGUST 7
+#define TM_SEPTEMBER 8
+#define TM_OCTOBER 9
+#define TM_NOVEMBER 10
+#define TM_DECEMBER 11
+
+#define TM_YEAR_BASE 1900
+#define TM_WDAY_BASE TM_MONDAY
+
+#define EPOCH_YEAR 1970
+#define EPOCH_WDAY TM_THURSDAY
+
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
/*
-** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
+** Since everything in isleap is modulo 400 (or a factor of 400), we know that
+** isleap(y) == isleap(y % 400)
+** and so
+** isleap(a + b) == isleap((a + b) % 400)
+** or
+** isleap(a + b) == isleap(a % 400 + b % 400)
+** This is true even if % means modulo rather than Fortran remainder
+** (which is allowed by C89 but not by C99 or later).
+** We use this to avoid addition overflow problems.
*/
-#ifndef AVGSECSPERYEAR
-#define AVGSECSPERYEAR 31556952L
-#endif /* !defined AVGSECSPERYEAR */
-
-#ifndef SECSPERREPEAT
-#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
-#endif /* !defined SECSPERREPEAT */
-
-#ifndef SECSPERREPEAT_BITS
-#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
-#endif /* !defined SECSPERREPEAT_BITS */
+#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
#endif /* !defined PRIVATE_H */
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index 7c4be49..d04c5ba 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -1,4 +1,4 @@
-/* Convert a broken-down time stamp to a string. */
+/* Convert a broken-down timestamp to a string. */
/* Copyright 1989 The Regents of the University of California.
All rights reserved.
@@ -35,9 +35,13 @@
#include "private.h"
-#include "tzfile.h"
-#include "fcntl.h"
-#include "locale.h"
+#include <fcntl.h>
+#include <locale.h>
+#include <stdio.h>
+
+#ifndef DEPRECATE_TWO_DIGIT_YEARS
+# define DEPRECATE_TWO_DIGIT_YEARS false
+#endif
#if defined(__BIONIC__)
@@ -45,6 +49,7 @@
#if defined(__LP64__)
#define time64_t time_t
#define mktime64 mktime
+#define localtime64_r localtime_r
#else
#include <time64.h>
#endif
@@ -88,7 +93,7 @@
/*
** x_fmt
- ** C99 requires this format.
+ ** C99 and later require this format.
** Using just numbers (as here) makes Quakers happier;
** it's also compatible with SVR4.
*/
@@ -96,7 +101,7 @@
/*
** c_fmt
- ** C99 requires this format.
+ ** C99 and later require this format.
** Previously this code used "%D %X", but we now conform to C99.
** Note that
** "%a %b %d %H:%M:%S %Y"
@@ -114,25 +119,18 @@
"%a %b %e %H:%M:%S %Z %Y"
};
+enum warn { IN_NONE, IN_SOME, IN_THIS, IN_ALL };
+
static char * _add(const char *, char *, const char *, int);
static char * _conv(int, const char *, char *, const char *);
static char * _fmt(const char *, const struct tm *, char *, const char *,
- int *);
+ enum warn *);
static char * _yconv(int, int, bool, bool, char *, const char *, int);
-#if !HAVE_POSIX_DECLS
-extern char * tzname[];
-#endif
-
#ifndef YEAR_2000_NAME
#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
#endif /* !defined YEAR_2000_NAME */
-#define IN_NONE 0
-#define IN_SOME 1
-#define IN_THIS 2
-#define IN_ALL 3
-
#if HAVE_STRFTIME_L
size_t
strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t,
@@ -149,18 +147,19 @@
strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
{
char * p;
- int warn;
+ int saved_errno = errno;
+ enum warn warn = IN_NONE;
tzset();
- warn = IN_NONE;
- p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
-#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
- if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
+ p = _fmt(format, t, s, s + maxsize, &warn);
+ if (!p) {
+ errno = EOVERFLOW;
+ return 0;
+ }
+ if (DEPRECATE_TWO_DIGIT_YEARS
+ && warn != IN_NONE && getenv(YEAR_2000_NAME)) {
fprintf(stderr, "\n");
- if (format == NULL)
- fprintf(stderr, "NULL strftime format ");
- else fprintf(stderr, "strftime format \"%s\" ",
- format);
+ fprintf(stderr, "strftime format \"%s\" ", format);
fprintf(stderr, "yields only two digits of years in ");
if (warn == IN_SOME)
fprintf(stderr, "some locales");
@@ -169,10 +168,12 @@
else fprintf(stderr, "all locales");
fprintf(stderr, "\n");
}
-#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
- if (p == s + maxsize)
+ if (p == s + maxsize) {
+ errno = ERANGE;
return 0;
+ }
*p = '\0';
+ errno = saved_errno;
return p - s;
}
@@ -189,9 +190,32 @@
return normal;
}
+// Android-added: fall back mechanism when TM_ZONE is not initialized.
+#ifdef TM_ZONE
+static const char* _safe_tm_zone(const struct tm* tm) {
+ const char* zone = tm->TM_ZONE;
+ if (!zone || !*zone) {
+ // "The value of tm_isdst shall be positive if Daylight Savings Time is
+ // in effect, 0 if Daylight Savings Time is not in effect, and negative
+ // if the information is not available."
+ if (tm->tm_isdst == 0) {
+ zone = tzname[0];
+ } else if (tm->tm_isdst > 0) {
+ zone = tzname[1];
+ }
+
+ // "Replaced by the timezone name or abbreviation, or by no bytes if no
+ // timezone information exists."
+ if (!zone || !*zone) zone = "";
+ }
+
+ return zone;
+}
+#endif
+
static char *
_fmt(const char *format, const struct tm *t, char *pt,
- const char *ptlim, int *warnp)
+ const char *ptlim, enum warn *warnp)
{
for ( ; *format; ++format) {
if (*format == '%') {
@@ -239,7 +263,7 @@
continue;
case 'c':
{
- int warn2 = IN_SOME;
+ enum warn warn2 = IN_SOME;
pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
if (warn2 == IN_ALL)
@@ -257,12 +281,12 @@
case 'E':
case 'O':
/*
- ** C99 locale modifiers.
+ ** Locale modifiers of C99 and later.
** The sequences
** %Ec %EC %Ex %EX %Ey %EY
** %Od %oe %OH %OI %Om %OM
** %OS %Ou %OU %OV %Ow %OW %Oy
- ** are supposed to provide alternate
+ ** are supposed to provide alternative
** representations.
*/
goto label;
@@ -356,11 +380,17 @@
tm = *t;
mkt = mktime64(&tm);
- if (TYPE_SIGNED(time64_t))
- snprintf(buf, sizeof(buf), "%"PRIdMAX,
- (intmax_t) mkt);
- else snprintf(buf, sizeof(buf), "%"PRIuMAX,
- (uintmax_t) mkt);
+ /* There is no portable, definitive
+ test for whether whether mktime
+ succeeded, so treat (time_t) -1 as
+ the success that it might be. */
+ if (TYPE_SIGNED(time64_t)) {
+ intmax_t n = mkt;
+ sprintf(buf, "%"PRIdMAX, n);
+ } else {
+ uintmax_t n = mkt;
+ sprintf(buf, "%"PRIuMAX, n);
+ }
pt = _add(buf, pt, ptlim, modifier);
}
continue;
@@ -392,7 +422,7 @@
** (01-53)."
** (ado, 1993-05-24)
**
-** From <http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html> by Markus Kuhn:
+** From <https://www.cl.cam.ac.uk/~mgk25/iso-time.html> by Markus Kuhn:
** "Week 01 of a year is per definition the first week which has the
** Thursday in this year, which is equivalent to the week which contains
** the fourth day of January. In other words, the first week of a new year
@@ -494,7 +524,7 @@
continue;
case 'x':
{
- int warn2 = IN_SOME;
+ enum warn warn2 = IN_SOME;
pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
if (warn2 == IN_ALL)
@@ -517,45 +547,32 @@
case 'Z':
#ifdef TM_ZONE
// BEGIN: Android-changed.
- {
- const char* zone = t->TM_ZONE;
- if (!zone || !*zone) {
- // "The value of tm_isdst shall be positive if Daylight Savings Time is
- // in effect, 0 if Daylight Savings Time is not in effect, and negative
- // if the information is not available."
- if (t->tm_isdst == 0) zone = tzname[0];
- else if (t->tm_isdst > 0) zone = tzname[1];
-
- // "Replaced by the timezone name or abbreviation, or by no bytes if no
- // timezone information exists."
- if (!zone || !*zone) zone = "";
- }
- pt = _add(zone, pt, ptlim, modifier);
- }
+ pt = _add(_safe_tm_zone(t), pt, ptlim, modifier);
// END: Android-changed.
-#else
+#elif HAVE_TZNAME
if (t->tm_isdst >= 0)
pt = _add(tzname[t->tm_isdst != 0],
pt, ptlim);
#endif
/*
- ** C99 says that %Z must be replaced by the
- ** empty string if the time zone is not
+ ** C99 and later say that %Z must be
+ ** replaced by the empty string if the
+ ** time zone abbreviation is not
** determinable.
*/
continue;
case 'z':
+#if defined TM_GMTOFF || USG_COMPAT || ALTZONE
{
long diff;
char const * sign;
+ bool negative;
- if (t->tm_isdst < 0)
- continue;
-#ifdef TM_GMTOFF
+# ifdef TM_GMTOFF
diff = t->TM_GMTOFF;
-#else /* !defined TM_GMTOFF */
+# else
/*
- ** C99 says that the UT offset must
+ ** C99 and later say that the UT offset must
** be computed by looking only at
** tm_isdst. This requirement is
** incorrect, since it means the code
@@ -563,30 +580,48 @@
** altzone and timezone), and the
** magic might not have the correct
** offset. Doing things correctly is
- ** tricky and requires disobeying C99;
+ ** tricky and requires disobeying the standard;
** see GNU C strftime for details.
** For now, punt and conform to the
** standard, even though it's incorrect.
**
- ** C99 says that %z must be replaced by the
- ** empty string if the time zone is not
+ ** C99 and later say that %z must be replaced by
+ ** the empty string if the time zone is not
** determinable, so output nothing if the
** appropriate variables are not available.
*/
+ if (t->tm_isdst < 0)
+ continue;
if (t->tm_isdst == 0)
-#ifdef USG_COMPAT
+# if USG_COMPAT
diff = -timezone;
-#else /* !defined USG_COMPAT */
+# else
continue;
-#endif /* !defined USG_COMPAT */
+# endif
else
-#ifdef ALTZONE
+# if ALTZONE
diff = -altzone;
-#else /* !defined ALTZONE */
+# else
continue;
-#endif /* !defined ALTZONE */
-#endif /* !defined TM_GMTOFF */
- if (diff < 0) {
+# endif
+# endif
+ negative = diff < 0;
+ if (diff == 0) {
+#ifdef TM_ZONE
+ // Android-changed: do not use TM_ZONE as it is as it may be null.
+ {
+ const char* zone = _safe_tm_zone(t);
+ negative = zone[0] == '-';
+ }
+#else
+ negative = t->tm_isdst < 0;
+# if HAVE_TZNAME
+ if (tzname[t->tm_isdst != 0][0] == '-')
+ negative = true;
+# endif
+#endif
+ }
+ if (negative) {
sign = "-";
diff = -diff;
} else sign = "+";
@@ -596,6 +631,7 @@
(diff % MINSPERHOUR);
pt = _conv(diff, getformat(modifier, "04", " 4", " ", "04"), pt, ptlim);
}
+#endif
continue;
case '+':
pt = _fmt(Locale->date_fmt, t, pt, ptlim,
diff --git a/libc/tzcode/tzfile.h b/libc/tzcode/tzfile.h
index ebecd68..c5f9967 100644
--- a/libc/tzcode/tzfile.h
+++ b/libc/tzcode/tzfile.h
@@ -1,3 +1,5 @@
+/* Layout and location of TZif files. */
+
#ifndef TZFILE_H
#define TZFILE_H
@@ -20,17 +22,20 @@
*/
#ifndef TZDIR
-#define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */
+#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
#endif /* !defined TZDIR */
#ifndef TZDEFAULT
-#define TZDEFAULT "localtime"
+#define TZDEFAULT "/etc/localtime"
#endif /* !defined TZDEFAULT */
#ifndef TZDEFRULES
#define TZDEFRULES "posixrules"
#endif /* !defined TZDEFRULES */
+
+/* See Internet RFC 8536 for more details about the following format. */
+
/*
** Each file begins with. . .
*/
@@ -39,9 +44,9 @@
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
- char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */
+ char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */
char tzh_reserved[15]; /* reserved; must be zero */
- char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
+ char tzh_ttisutcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
char tzh_timecnt[4]; /* coded number of transition times */
@@ -64,14 +69,15 @@
** one (char [4]) total correction after above
** tzh_ttisstdcnt (char)s indexed by type; if 1, transition
** time is standard time, if 0,
-** transition time is wall clock time
-** if absent, transition times are
-** assumed to be wall clock time
-** tzh_ttisgmtcnt (char)s indexed by type; if 1, transition
-** time is UT, if 0,
-** transition time is local time
-** if absent, transition times are
+** transition time is local (wall clock)
+** time; if absent, transition times are
** assumed to be local time
+** tzh_ttisutcnt (char)s indexed by type; if 1, transition
+** time is UT, if 0, transition time is
+** local time; if absent, transition
+** times are assumed to be local time.
+** When this is 1, the corresponding
+** std/wall indicator must also be 1.
*/
/*
diff --git a/libc/upstream-freebsd/lib/libc/string/bcopy.c b/libc/upstream-freebsd/lib/libc/string/bcopy.c
new file mode 100644
index 0000000..84715d0
--- /dev/null
+++ b/libc/upstream-freebsd/lib/libc/string/bcopy.c
@@ -0,0 +1,137 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+typedef intptr_t word; /* "word" used for optimal copy speed */
+
+#define wsize sizeof(word)
+#define wmask (wsize - 1)
+
+/*
+ * Copy a block of memory, handling overlap.
+ * This is the routine that actually implements
+ * (the portable versions of) bcopy, memcpy, and memmove.
+ */
+#if defined(MEMCOPY) || defined(MEMMOVE)
+#include <string.h>
+
+void *
+#ifdef MEMCOPY
+memcpy
+#else
+memmove
+#endif
+(void *dst0, const void *src0, size_t length)
+#else
+#include <strings.h>
+
+void
+bcopy(const void *src0, void *dst0, size_t length)
+#endif
+{
+ char *dst = dst0;
+ const char *src = src0;
+ size_t t;
+
+ if (length == 0 || dst == src) /* nothing to do */
+ goto done;
+
+ /*
+ * Macros: loop-t-times; and loop-t-times, t>0
+ */
+#define TLOOP(s) if (t) TLOOP1(s)
+#define TLOOP1(s) do { s; } while (--t)
+
+ if ((unsigned long)dst < (unsigned long)src) {
+ /*
+ * Copy forward.
+ */
+ t = (uintptr_t)src; /* only need low bits */
+ if ((t | (uintptr_t)dst) & wmask) {
+ /*
+ * Try to align operands. This cannot be done
+ * unless the low bits match.
+ */
+ if ((t ^ (uintptr_t)dst) & wmask || length < wsize)
+ t = length;
+ else
+ t = wsize - (t & wmask);
+ length -= t;
+ TLOOP1(*dst++ = *src++);
+ }
+ /*
+ * Copy whole words, then mop up any trailing bytes.
+ */
+ t = length / wsize;
+ TLOOP(*(word *)(void *)dst = *(const word *)(const void *)src;
+ src += wsize; dst += wsize);
+ t = length & wmask;
+ TLOOP(*dst++ = *src++);
+ } else {
+ /*
+ * Copy backwards. Otherwise essentially the same.
+ * Alignment works as before, except that it takes
+ * (t&wmask) bytes to align, not wsize-(t&wmask).
+ */
+ src += length;
+ dst += length;
+ t = (uintptr_t)src;
+ if ((t | (uintptr_t)dst) & wmask) {
+ if ((t ^ (uintptr_t)dst) & wmask || length <= wsize)
+ t = length;
+ else
+ t &= wmask;
+ length -= t;
+ TLOOP1(*--dst = *--src);
+ }
+ t = length / wsize;
+ TLOOP(src -= wsize; dst -= wsize;
+ *(word *)(void *)dst = *(const word *)(const void *)src);
+ t = length & wmask;
+ TLOOP(*--dst = *--src);
+ }
+done:
+#if defined(MEMCOPY) || defined(MEMMOVE)
+ return (dst0);
+#else
+ return;
+#endif
+}
diff --git a/libc/upstream-freebsd/lib/libc/string/memcmp.c b/libc/upstream-freebsd/lib/libc/string/memcmp.c
new file mode 100644
index 0000000..c8d5d92
--- /dev/null
+++ b/libc/upstream-freebsd/lib/libc/string/memcmp.c
@@ -0,0 +1,58 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <string.h>
+
+/*
+ * Compare memory regions.
+ */
+int
+memcmp(const void *s1, const void *s2, size_t n)
+{
+ if (n != 0) {
+ const unsigned char *p1 = s1, *p2 = s2;
+
+ do {
+ if (*p1++ != *p2++)
+ return (*--p1 - *--p2);
+ } while (--n != 0);
+ }
+ return (0);
+}
diff --git a/libc/upstream-freebsd/lib/libc/string/memcpy.c b/libc/upstream-freebsd/lib/libc/string/memcpy.c
new file mode 100644
index 0000000..ed03856
--- /dev/null
+++ b/libc/upstream-freebsd/lib/libc/string/memcpy.c
@@ -0,0 +1,5 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define MEMCOPY
+#include "bcopy.c"
diff --git a/libc/upstream-freebsd/lib/libc/string/memmove.c b/libc/upstream-freebsd/lib/libc/string/memmove.c
new file mode 100644
index 0000000..05cf75a
--- /dev/null
+++ b/libc/upstream-freebsd/lib/libc/string/memmove.c
@@ -0,0 +1,5 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define MEMMOVE
+#include "bcopy.c"
diff --git a/libc/upstream-freebsd/lib/libc/string/memset.c b/libc/upstream-freebsd/lib/libc/string/memset.c
new file mode 100644
index 0000000..e2d4027
--- /dev/null
+++ b/libc/upstream-freebsd/lib/libc/string/memset.c
@@ -0,0 +1,133 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Hibler and Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)memset.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include <limits.h>
+
+#define wsize sizeof(u_long)
+#define wmask (wsize - 1)
+
+#ifdef BZERO
+#include <strings.h>
+
+#define RETURN return
+#define VAL 0
+#define WIDEVAL 0
+
+void
+bzero(void *dst0, size_t length)
+#else
+#include <string.h>
+
+#define RETURN return (dst0)
+#define VAL c0
+#define WIDEVAL c
+
+void *
+memset(void *dst0, int c0, size_t length)
+#endif
+{
+ size_t t;
+#ifndef BZERO
+ u_long c;
+#endif
+ u_char *dst;
+
+ dst = dst0;
+ /*
+ * If not enough words, just fill bytes. A length >= 2 words
+ * guarantees that at least one of them is `complete' after
+ * any necessary alignment. For instance:
+ *
+ * |-----------|-----------|-----------|
+ * |00|01|02|03|04|05|06|07|08|09|0A|00|
+ * ^---------------------^
+ * dst dst+length-1
+ *
+ * but we use a minimum of 3 here since the overhead of the code
+ * to do word writes is substantial.
+ *
+ * TODO: This threshold might not be sensible for 64-bit u_long.
+ * We should benchmark and revisit this decision.
+ */
+ if (length < 3 * wsize) {
+ while (length != 0) {
+ *dst++ = VAL;
+ --length;
+ }
+ RETURN;
+ }
+
+#ifndef BZERO
+ if ((c = (u_char)c0) != 0) { /* Fill the word. */
+ c = (c << 8) | c; /* u_long is 16 bits. */
+#if ULONG_MAX > 0xffff
+ c = (c << 16) | c; /* u_long is 32 bits. */
+#endif
+#if ULONG_MAX > 0xffffffff
+ c = (c << 32) | c; /* u_long is 64 bits. */
+#endif
+ }
+#endif
+ /* Align destination by filling in bytes. */
+ if ((t = (long)dst & wmask) != 0) {
+ t = wsize - t;
+ length -= t;
+ do {
+ *dst++ = VAL;
+ } while (--t != 0);
+ }
+
+ /* Fill words. Length was >= 2*words so we know t >= 1 here. */
+ t = length / wsize;
+ do {
+ *(u_long *)(void *)dst = WIDEVAL;
+ dst += wsize;
+ } while (--t != 0);
+
+ /* Mop up trailing bytes, if any. */
+ t = length & wmask;
+ if (t != 0)
+ do {
+ *dst++ = VAL;
+ } while (--t != 0);
+ RETURN;
+}
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/misc.c b/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
index 79a3104..fef51a9 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
@@ -41,7 +41,7 @@
#endif
#ifdef MULTIPLE_THREADS
-extern void *__dtoa_locks[];
+static void *__dtoa_locks[] = { NULL, NULL };
#endif
Bigint *
diff --git a/libc/upstream-openbsd/lib/libc/gen/alarm.c b/libc/upstream-openbsd/lib/libc/gen/alarm.c
index f15dd15..ac17f9d 100644
--- a/libc/upstream-openbsd/lib/libc/gen/alarm.c
+++ b/libc/upstream-openbsd/lib/libc/gen/alarm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: alarm.c,v 1.9 2019/06/28 13:32:41 deraadt Exp $ */
+/* $OpenBSD: alarm.c,v 1.10 2021/06/24 22:43:31 cheloha Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -34,13 +34,12 @@
unsigned int
alarm(unsigned int secs)
{
- struct itimerval it, oitv;
- struct itimerval *itp = ⁢
+ struct itimerval itv, oitv;
- timerclear(&itp->it_interval);
- itp->it_value.tv_sec = secs;
- itp->it_value.tv_usec = 0;
- if (setitimer(ITIMER_REAL, itp, &oitv) == -1)
+ timerclear(&itv.it_interval);
+ itv.it_value.tv_sec = secs;
+ itv.it_value.tv_usec = 0;
+ if (setitimer(ITIMER_REAL, &itv, &oitv) == -1)
return ((unsigned int) -1);
if (oitv.it_value.tv_usec)
oitv.it_value.tv_sec++;
diff --git a/libc/upstream-openbsd/lib/libc/gen/charclass.h b/libc/upstream-openbsd/lib/libc/gen/charclass.h
index 073baf6..1d1ec07 100644
--- a/libc/upstream-openbsd/lib/libc/gen/charclass.h
+++ b/libc/upstream-openbsd/lib/libc/gen/charclass.h
@@ -1,13 +1,13 @@
/*
* Public domain, 2008, Todd C. Miller <millert@openbsd.org>
*
- * $OpenBSD: charclass.h,v 1.2 2019/01/25 00:19:25 millert Exp $
+ * $OpenBSD: charclass.h,v 1.3 2020/10/13 04:42:28 guenther Exp $
*/
/*
* POSIX character class support for fnmatch() and glob().
*/
-static struct cclass {
+static const struct cclass {
const char *name;
int (*isctype)(int);
} cclasses[] = {
diff --git a/libc/upstream-openbsd/lib/libc/gen/daemon.c b/libc/upstream-openbsd/lib/libc/gen/daemon.c
index 79f4264..b84cb4f 100644
--- a/libc/upstream-openbsd/lib/libc/gen/daemon.c
+++ b/libc/upstream-openbsd/lib/libc/gen/daemon.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: daemon.c,v 1.7 2010/07/27 22:29:09 marco Exp $ */
+/* $OpenBSD: daemon.c,v 1.8 2021/10/24 21:24:20 deraadt Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -53,7 +53,7 @@
if (!nochdir)
(void)chdir("/");
- if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR)) != -1) {
(void)dup2(fd, STDIN_FILENO);
(void)dup2(fd, STDOUT_FILENO);
(void)dup2(fd, STDERR_FILENO);
diff --git a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
index d7afd5f..ff6b26e 100644
--- a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
+++ b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fnmatch.c,v 1.22 2020/03/13 03:25:45 djm Exp $ */
+/* $OpenBSD: fnmatch.c,v 1.23 2020/10/13 04:42:28 guenther Exp $ */
/* Copyright (c) 2011, VMware, Inc.
* All rights reserved.
@@ -100,7 +100,7 @@
{
const char * const mismatch = pattern;
const char *colon;
- struct cclass *cc;
+ const struct cclass *cc;
int rval = RANGE_NOMATCH;
size_t len;
diff --git a/libc/upstream-openbsd/lib/libc/gen/ftok.c b/libc/upstream-openbsd/lib/libc/gen/ftok.c
index ea1edf1..9edcd30 100644
--- a/libc/upstream-openbsd/lib/libc/gen/ftok.c
+++ b/libc/upstream-openbsd/lib/libc/gen/ftok.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftok.c,v 1.9 2019/06/28 13:32:41 deraadt Exp $ */
+/* $OpenBSD: ftok.c,v 1.10 2022/04/13 16:23:53 millert Exp $ */
/*
* Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
* All rights reserved.
@@ -32,11 +32,12 @@
key_t
ftok(const char *path, int id)
{
+ const unsigned int u_id = id;
struct stat st;
if (stat(path, &st) == -1)
return (key_t)-1;
return (key_t)
- ((id & 0xff) << 24 | (st.st_dev & 0xff) << 16 | (st.st_ino & 0xffff));
+ ((u_id & 0xff) << 24 | (st.st_dev & 0xff) << 16 | (st.st_ino & 0xffff));
}
diff --git a/libc/upstream-openbsd/lib/libc/locale/_wcstol.h b/libc/upstream-openbsd/lib/libc/locale/_wcstol.h
deleted file mode 100644
index 1b60a3a..0000000
--- a/libc/upstream-openbsd/lib/libc/locale/_wcstol.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* $OpenBSD: _wcstol.h,v 1.3 2015/10/01 02:32:07 guenther Exp $ */
-/* $NetBSD: _wcstol.h,v 1.2 2003/08/07 16:43:03 agc Exp $ */
-
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Original version ID:
- * @(#)strtol.c 8.1 (Berkeley) 6/4/93
- * NetBSD: wcstol.c,v 1.1 2001/09/27 16:30:36 yamt Exp
- * Citrus: xpg4dl/FreeBSD/lib/libc/locale/wcstol.c,v 1.2 2001/09/21 16:11:41 yamt Exp
- */
-
-/*
- * function template for wcstol, wcstoll and wcstoimax.
- *
- * parameters:
- * FUNCNAME : function name
- * int_type : return type
- * MIN_VALUE : lower limit of the return type
- * MAX_VALUE : upper limit of the return type
- */
-
-int_type
-FUNCNAME(const wchar_t *nptr, wchar_t **endptr, int base)
-{
- const wchar_t *s;
- int_type acc, cutoff;
- wint_t wc;
- int i;
- int neg, any, cutlim;
-
- /* check base value */
- if (base && (base < 2 || base > 36)) {
- errno = EINVAL;
- return 0;
- }
-
- /*
- * Skip white space and pick up leading +/- sign if any.
- * If base is 0, allow 0x for hex and 0 for octal, else
- * assume decimal; if base is already 16, allow 0x.
- */
- s = nptr;
- do {
- wc = (wchar_t) *s++;
- } while (iswspace(wc));
- if (wc == L'-') {
- neg = 1;
- wc = *s++;
- } else {
- neg = 0;
- if (wc == L'+')
- wc = *s++;
- }
- if ((base == 0 || base == 16) &&
- wc == L'0' && (*s == L'x' || *s == L'X')) {
- wc = s[1];
- s += 2;
- base = 16;
- }
- if (base == 0)
- base = wc == L'0' ? 8 : 10;
-
- /*
- * See strtol for comments as to the logic used.
- */
- cutoff = neg ? MIN_VALUE : MAX_VALUE;
- cutlim = (int)(cutoff % base);
- cutoff /= base;
- if (neg) {
- if (cutlim > 0) {
- cutlim -= base;
- cutoff += 1;
- }
- cutlim = -cutlim;
- }
- for (acc = 0, any = 0;; wc = (wchar_t) *s++) {
- i = wctoint(wc);
- if (i == -1)
- break;
- if (i >= base)
- break;
- if (any < 0)
- continue;
- if (neg) {
- if (acc < cutoff || (acc == cutoff && i > cutlim)) {
- any = -1;
- acc = MIN_VALUE;
- errno = ERANGE;
- } else {
- any = 1;
- acc *= base;
- acc -= i;
- }
- } else {
- if (acc > cutoff || (acc == cutoff && i > cutlim)) {
- any = -1;
- acc = MAX_VALUE;
- errno = ERANGE;
- } else {
- any = 1;
- acc *= base;
- acc += i;
- }
- }
- }
- if (endptr != 0)
- *endptr = (wchar_t *)(any ? s - 1 : nptr);
- return (acc);
-}
-DEF_STRONG(FUNCNAME);
diff --git a/libc/upstream-openbsd/lib/libc/locale/_wcstoul.h b/libc/upstream-openbsd/lib/libc/locale/_wcstoul.h
deleted file mode 100644
index 159b22b..0000000
--- a/libc/upstream-openbsd/lib/libc/locale/_wcstoul.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* $OpenBSD: _wcstoul.h,v 1.3 2015/10/01 02:32:07 guenther Exp $ */
-/* $NetBSD: _wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp $ */
-
-/*
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Original version ID:
- * @(#)strtoul.c 8.1 (Berkeley) 6/4/93
- * Citrus: xpg4dl/FreeBSD/lib/libc/locale/wcstoul.c,v 1.2 2001/09/21 16:11:41 yamt Exp
- * NetBSD: wcstoul.c,v 1.1 2001/09/27 16:30:37 yamt Exp
- */
-
-/*
- * function template for wcstoul, wcstoull and wcstoumax.
- *
- * parameters:
- * FUNCNAME : function name
- * uint_type : return type
- * MAX_VALUE : upper limit of the return type
- */
-
-uint_type
-FUNCNAME(const wchar_t *nptr, wchar_t **endptr, int base)
-{
- const wchar_t *s;
- uint_type acc, cutoff;
- wint_t wc;
- int i;
- int neg, any, cutlim;
-
- if (base && (base < 2 || base > 36)) {
- errno = EINVAL;
- return 0;
- }
-
- /*
- * Skip white space and pick up leading +/- sign if any.
- * If base is 0, allow 0x for hex and 0 for octal, else
- * assume decimal; if base is already 16, allow 0x.
- */
- s = nptr;
- do {
- wc = (wchar_t) *s++;
- } while (iswspace(wc));
- if (wc == L'-') {
- neg = 1;
- wc = *s++;
- } else {
- neg = 0;
- if (wc == L'+')
- wc = *s++;
- }
- if ((base == 0 || base == 16) &&
- wc == L'0' && (*s == L'x' || *s == L'X')) {
- wc = s[1];
- s += 2;
- base = 16;
- }
- if (base == 0)
- base = wc == L'0' ? 8 : 10;
-
- /*
- * See strtoul for comments as to the logic used.
- */
- cutoff = MAX_VALUE / (uint_type)base;
- cutlim = (int)(MAX_VALUE % (uint_type)base);
- for (acc = 0, any = 0;; wc = (wchar_t) *s++) {
- i = wctoint(wc);
- if (i == (wint_t)-1)
- break;
- if (i >= base)
- break;
- if (any < 0)
- continue;
- if (acc > cutoff || (acc == cutoff && i > cutlim)) {
- any = -1;
- acc = MAX_VALUE;
- errno = ERANGE;
- } else {
- any = 1;
- acc *= (uint_type)base;
- acc += i;
- }
- }
- if (neg && any > 0)
- acc = -acc;
- if (endptr != 0)
- *endptr = (wchar_t *)(any ? s - 1 : nptr);
- return (acc);
-}
-DEF_STRONG(FUNCNAME);
diff --git a/libc/upstream-openbsd/lib/libc/locale/wcstoimax.c b/libc/upstream-openbsd/lib/libc/locale/wcstoimax.c
deleted file mode 100644
index d46a7c7..0000000
--- a/libc/upstream-openbsd/lib/libc/locale/wcstoimax.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $OpenBSD: wcstoimax.c,v 1.1 2009/01/13 18:13:51 kettenis Exp $ */
-/* $NetBSD: wcstol.c,v 1.2 2003/03/11 09:21:23 tshiozak Exp $ */
-
-#include <ctype.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "wctoint.h"
-
-#define FUNCNAME wcstoimax
-typedef intmax_t int_type;
-#define MIN_VALUE INTMAX_MIN
-#define MAX_VALUE INTMAX_MAX
-
-#include "_wcstol.h"
diff --git a/libc/upstream-openbsd/lib/libc/locale/wcstol.c b/libc/upstream-openbsd/lib/libc/locale/wcstol.c
deleted file mode 100644
index 03395a0..0000000
--- a/libc/upstream-openbsd/lib/libc/locale/wcstol.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* $OpenBSD: wcstol.c,v 1.2 2005/08/08 08:05:35 espie Exp $ */
-/* $NetBSD: wcstol.c,v 1.2 2003/03/11 09:21:23 tshiozak Exp $ */
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "wctoint.h"
-
-#define FUNCNAME wcstol
-typedef long int_type;
-#define MIN_VALUE LONG_MIN
-#define MAX_VALUE LONG_MAX
-
-#include "_wcstol.h"
diff --git a/libc/upstream-openbsd/lib/libc/locale/wcstoll.c b/libc/upstream-openbsd/lib/libc/locale/wcstoll.c
deleted file mode 100644
index 926db70..0000000
--- a/libc/upstream-openbsd/lib/libc/locale/wcstoll.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* $OpenBSD: wcstoll.c,v 1.2 2005/08/08 08:05:35 espie Exp $ */
-/* $NetBSD: wcstoll.c,v 1.1 2003/03/11 09:21:23 tshiozak Exp $ */
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "wctoint.h"
-
-#define FUNCNAME wcstoll
-typedef long long int int_type;
-#define MIN_VALUE LLONG_MIN
-#define MAX_VALUE LLONG_MAX
-
-#include "_wcstol.h"
diff --git a/libc/upstream-openbsd/lib/libc/locale/wcstoul.c b/libc/upstream-openbsd/lib/libc/locale/wcstoul.c
deleted file mode 100644
index e863862..0000000
--- a/libc/upstream-openbsd/lib/libc/locale/wcstoul.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* $OpenBSD: wcstoul.c,v 1.2 2005/08/08 08:05:35 espie Exp $ */
-/* $NetBSD: wcstoul.c,v 1.2 2003/03/11 09:21:24 tshiozak Exp $ */
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "wctoint.h"
-
-#define FUNCNAME wcstoul
-typedef unsigned long uint_type;
-#define MAX_VALUE ULONG_MAX
-
-#include "_wcstoul.h"
diff --git a/libc/upstream-openbsd/lib/libc/locale/wcstoull.c b/libc/upstream-openbsd/lib/libc/locale/wcstoull.c
deleted file mode 100644
index 6671c37..0000000
--- a/libc/upstream-openbsd/lib/libc/locale/wcstoull.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* $OpenBSD: wcstoull.c,v 1.2 2005/08/08 08:05:35 espie Exp $ */
-/* $NetBSD: wcstoull.c,v 1.1 2003/03/11 09:21:24 tshiozak Exp $ */
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "wctoint.h"
-
-#define FUNCNAME wcstoull
-typedef unsigned long long int uint_type;
-#define MAX_VALUE ULLONG_MAX
-
-#include "_wcstoul.h"
diff --git a/libc/upstream-openbsd/lib/libc/locale/wcstoumax.c b/libc/upstream-openbsd/lib/libc/locale/wcstoumax.c
deleted file mode 100644
index ccd4713..0000000
--- a/libc/upstream-openbsd/lib/libc/locale/wcstoumax.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* $OpenBSD: wcstoumax.c,v 1.1 2009/01/13 18:13:51 kettenis Exp $ */
-/* $NetBSD: wcstoul.c,v 1.2 2003/03/11 09:21:24 tshiozak Exp $ */
-
-#include <ctype.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "wctoint.h"
-
-#define FUNCNAME wcstoumax
-typedef uintmax_t uint_type;
-#define MAX_VALUE UINTMAX_MAX
-
-#include "_wcstoul.h"
diff --git a/libc/upstream-openbsd/lib/libc/locale/wctoint.h b/libc/upstream-openbsd/lib/libc/locale/wctoint.h
deleted file mode 100644
index ea50c5a..0000000
--- a/libc/upstream-openbsd/lib/libc/locale/wctoint.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* $OpenBSD: wctoint.h,v 1.2 2015/09/13 11:38:08 guenther Exp $ */
-/* $NetBSD: __wctoint.h,v 1.1 2001/09/28 11:25:37 yamt Exp $ */
-
-/*-
- * Copyright (c)2001 Citrus Project,
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Citrus: xpg4dl/FreeBSD/lib/libc/locale/__wctoint.h,v 1.1 2001/09/21 13:52:32 yamt Exp $
- */
-
-
-inline static int
-wctoint(wchar_t wc)
-{
- int n;
-
- switch (wc) {
- case L'0': n = 0; break;
- case L'1': n = 1; break;
- case L'2': n = 2; break;
- case L'3': n = 3; break;
- case L'4': n = 4; break;
- case L'5': n = 5; break;
- case L'6': n = 6; break;
- case L'7': n = 7; break;
- case L'8': n = 8; break;
- case L'9': n = 9; break;
- case L'A': case L'a': n = 10; break;
- case L'B': case L'b': n = 11; break;
- case L'C': case L'c': n = 12; break;
- case L'D': case L'd': n = 13; break;
- case L'E': case L'e': n = 14; break;
- case L'F': case L'f': n = 15; break;
- case L'G': case L'g': n = 16; break;
- case L'H': case L'h': n = 17; break;
- case L'I': case L'i': n = 18; break;
- case L'J': case L'j': n = 19; break;
- case L'K': case L'k': n = 20; break;
- case L'L': case L'l': n = 21; break;
- case L'M': case L'm': n = 22; break;
- case L'N': case L'n': n = 23; break;
- case L'O': case L'o': n = 24; break;
- case L'P': case L'p': n = 25; break;
- case L'Q': case L'q': n = 26; break;
- case L'R': case L'r': n = 27; break;
- case L'S': case L's': n = 28; break;
- case L'T': case L't': n = 29; break;
- case L'U': case L'u': n = 30; break;
- case L'V': case L'v': n = 31; break;
- case L'W': case L'w': n = 32; break;
- case L'X': case L'x': n = 33; break;
- case L'Y': case L'y': n = 34; break;
- case L'Z': case L'z': n = 35; break;
- default: n = -1; break; /* error */
- }
-
- return n;
-}
diff --git a/libc/upstream-openbsd/lib/libc/net/base64.c b/libc/upstream-openbsd/lib/libc/net/base64.c
index e90696d..f36c11a 100644
--- a/libc/upstream-openbsd/lib/libc/net/base64.c
+++ b/libc/upstream-openbsd/lib/libc/net/base64.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $ */
+/* $OpenBSD: base64.c,v 1.15 2021/10/25 14:41:09 jca Exp $ */
/*
* Copyright (c) 1996 by Internet Software Consortium.
@@ -46,11 +46,9 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#include <arpa/nameser.h>
#include <ctype.h>
#include <resolv.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -107,9 +105,9 @@
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
- -------------------------------------------------
+ -------------------------------------------------
following cases can arise:
-
+
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
@@ -123,15 +121,12 @@
*/
int
-b64_ntop(src, srclength, target, targsize)
- u_char const *src;
- size_t srclength;
- char *target;
- size_t targsize;
+b64_ntop(unsigned char const *src, size_t srclength, char *target,
+ size_t targsize)
{
size_t datalength = 0;
- u_char input[3];
- u_char output[4];
+ unsigned char input[3];
+ unsigned char output[4];
int i;
while (2 < srclength) {
@@ -152,14 +147,14 @@
target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]];
}
-
+
/* Now we worry about padding. */
if (0 != srclength) {
/* Get what's left. */
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclength; i++)
input[i] = *src++;
-
+
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
@@ -187,13 +182,10 @@
*/
int
-b64_pton(src, target, targsize)
- char const *src;
- u_char *target;
- size_t targsize;
+b64_pton(char const *src, unsigned char *target, size_t targsize)
{
int tarindex, state, ch;
- u_char nextbyte;
+ unsigned char nextbyte;
char *pos;
state = 0;
@@ -207,7 +199,7 @@
break;
pos = strchr(Base64, ch);
- if (pos == 0) /* A non-base64 character. */
+ if (pos == 0) /* A non-base64 character. */
return (-1);
switch (state) {
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fputws.c b/libc/upstream-openbsd/lib/libc/stdio/fputws.c
index 8961571..4f619b6 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fputws.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fputws.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fputws.c,v 1.8 2015/08/31 02:53:57 guenther Exp $ */
+/* $OpenBSD: fputws.c,v 1.9 2021/10/24 10:05:23 jsg Exp $ */
/* $NetBSD: fputws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp $ */
/*-
@@ -37,9 +37,7 @@
#include "fvwrite.h"
int
-fputws(ws, fp)
- const wchar_t * __restrict ws;
- FILE * __restrict fp;
+fputws(const wchar_t * __restrict ws, FILE * __restrict fp)
{
FLOCKFILE(fp);
_SET_ORIENTATION(fp, 1);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
index da68b90..9a08d13 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
@@ -131,7 +131,8 @@
flags |= __SNPT;
/*
- * Fix up the FILE fields.
+ * Fix up the FILE fields, and set __cleanup for output flush on
+ * exit (since we are buffered in some way).
*/
if (mode == _IOLBF)
flags |= __SLBF;
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/lsearch.c b/libc/upstream-openbsd/lib/libc/stdlib/lsearch.c
index 8cad05f..95ebf49 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/lsearch.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/lsearch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lsearch.c,v 1.5 2014/07/18 04:16:09 matthew Exp $ */
+/* $OpenBSD: lsearch.c,v 1.7 2021/12/08 22:06:28 cheloha Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -37,48 +37,34 @@
#include <search.h>
typedef int (*cmp_fn_t)(const void *, const void *);
-static void *linear_base(const void *, const void *, size_t *, size_t,
- cmp_fn_t, int);
void *
lsearch(const void *key, void *base, size_t *nelp, size_t width,
cmp_fn_t compar)
{
+ void *element = lfind(key, base, nelp, width, compar);
- return(linear_base(key, base, nelp, width, compar, 1));
+ /*
+ * Use memmove(3) to ensure the key is copied cleanly into the
+ * array, even if the key overlaps with the end of the array.
+ */
+ if (element == NULL) {
+ element = memmove((char *)base + *nelp * width, key, width);
+ *nelp += 1;
+ }
+ return element;
}
void *
lfind(const void *key, const void *base, size_t *nelp, size_t width,
cmp_fn_t compar)
{
- return(linear_base(key, base, nelp, width, compar, 0));
-}
-
-static void *
-linear_base(const void *key, const void *base, size_t *nelp, size_t width,
- cmp_fn_t compar, int add_flag)
-{
const char *element, *end;
end = (const char *)base + *nelp * width;
for (element = base; element < end; element += width)
if (!compar(key, element)) /* key found */
return((void *)element);
-
- if (!add_flag) /* key not found */
- return(NULL);
-
- /*
- * The UNIX System User's Manual, 1986 edition claims that
- * a NULL pointer is returned by lsearch with errno set
- * appropriately, if there is not enough room in the table
- * to add a new item. This can't be done as none of these
- * routines have any method of determining the size of the
- * table. This comment isn't in the 1986-87 System V
- * manual.
- */
- ++*nelp;
- memcpy((void *)end, key, width);
- return((void *)end);
+ return NULL;
}
+DEF_WEAK(lfind);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/recallocarray.c b/libc/upstream-openbsd/lib/libc/stdlib/recallocarray.c
index a2f37fe..81059e6 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/recallocarray.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/recallocarray.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */
+/* $OpenBSD: recallocarray.c,v 1.2 2021/03/18 11:16:58 claudio Exp $ */
/*
* Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
*
@@ -57,7 +57,7 @@
if (newsize <= oldsize) {
size_t d = oldsize - newsize;
- if (d < oldsize / 2 && d < getpagesize()) {
+ if (d < oldsize / 2 && d < (size_t)getpagesize()) {
memset((char *)ptr + newsize, 0, d);
return ptr;
}
diff --git a/libc/versioner-dependencies/riscv64/kernel_uapi_asm-riscv64 b/libc/versioner-dependencies/riscv64/kernel_uapi_asm-riscv64
new file mode 120000
index 0000000..61353cb
--- /dev/null
+++ b/libc/versioner-dependencies/riscv64/kernel_uapi_asm-riscv64
@@ -0,0 +1 @@
+../../kernel/uapi/asm-riscv/
\ No newline at end of file
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 750a6e2..4cdec44 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -74,6 +74,7 @@
"-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
"-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
"-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-riscv64-android.a",
"-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
],
@@ -87,6 +88,9 @@
arm64: {
version_script: ":libdl.arm64.map",
},
+ riscv64: {
+ version_script: ":libdl.riscv64.map",
+ },
x86: {
pack_relocations: false,
ldflags: [
@@ -174,6 +178,7 @@
"-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
"-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
"-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-riscv64-android.a",
"-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
],
@@ -241,30 +246,38 @@
name: "libdl.arm.map",
out: ["libdl.arm.map"],
srcs: ["libdl.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) arm $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) arm $(in) $(out)",
}
genrule {
name: "libdl.arm64.map",
out: ["libdl.arm64.map"],
srcs: ["libdl.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) arm64 $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) arm64 $(in) $(out)",
+}
+
+genrule {
+ name: "libdl.riscv64.map",
+ out: ["libdl.riscv64.map"],
+ srcs: ["libdl.map.txt"],
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
}
genrule {
name: "libdl.x86.map",
out: ["libdl.x86.map"],
srcs: ["libdl.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) x86 $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) x86 $(in) $(out)",
}
genrule {
name: "libdl.x86_64.map",
out: ["libdl.x86_64.map"],
srcs: ["libdl.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) x86_64 $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
}
diff --git a/libm/Android.bp b/libm/Android.bp
index 7469cde..8024fbe 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -73,8 +73,6 @@
"upstream-freebsd/lib/msun/src/e_scalbf.c",
"upstream-freebsd/lib/msun/src/e_sinh.c",
"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/k_cos.c",
"upstream-freebsd/lib/msun/src/k_cosf.c",
"upstream-freebsd/lib/msun/src/k_exp.c",
@@ -282,24 +280,16 @@
},
},
- // arch-specific settings
arch: {
arm: {
srcs: [
"arm/fenv.c",
+ "arm/floor.S",
+ "arm/sqrt.S",
],
- neon: {
- srcs: [
- "arm/sqrt.S",
- "arm/floor.S",
- ],
-
- exclude_srcs: [
- "upstream-freebsd/lib/msun/src/e_sqrt.c",
- "upstream-freebsd/lib/msun/src/e_sqrtf.c",
- "upstream-freebsd/lib/msun/src/s_floor.c",
- ],
- },
+ exclude_srcs: [
+ "upstream-freebsd/lib/msun/src/s_floor.c",
+ ],
instruction_set: "arm",
pack_relocations: false,
ldflags: ["-Wl,--hash-style=both"],
@@ -318,10 +308,10 @@
"arm64/sqrt.S",
],
exclude_srcs: [
- "upstream-freebsd/lib/msun/src/e_sqrt.c",
- "upstream-freebsd/lib/msun/src/e_sqrtf.c",
"upstream-freebsd/lib/msun/src/s_ceil.c",
"upstream-freebsd/lib/msun/src/s_ceilf.c",
+ "upstream-freebsd/lib/msun/src/s_copysign.c",
+ "upstream-freebsd/lib/msun/src/s_copysignf.c",
"upstream-freebsd/lib/msun/src/s_floor.c",
"upstream-freebsd/lib/msun/src/s_floorf.c",
"upstream-freebsd/lib/msun/src/s_fma.c",
@@ -332,8 +322,12 @@
"upstream-freebsd/lib/msun/src/s_fminf.c",
"upstream-freebsd/lib/msun/src/s_llrint.c",
"upstream-freebsd/lib/msun/src/s_llrintf.c",
+ "upstream-freebsd/lib/msun/src/s_llround.c",
+ "upstream-freebsd/lib/msun/src/s_llroundf.c",
"upstream-freebsd/lib/msun/src/s_lrint.c",
"upstream-freebsd/lib/msun/src/s_lrintf.c",
+ "upstream-freebsd/lib/msun/src/s_lround.c",
+ "upstream-freebsd/lib/msun/src/s_lroundf.c",
"upstream-freebsd/lib/msun/src/s_rint.c",
"upstream-freebsd/lib/msun/src/s_rintf.c",
"upstream-freebsd/lib/msun/src/s_round.c",
@@ -344,6 +338,22 @@
version_script: ":libm.arm64.map",
},
+ riscv64: {
+ srcs: [
+ "riscv64/fenv.c",
+ "riscv64/lrint.S",
+ "riscv64/sqrt.S",
+ ],
+
+ exclude_srcs: [
+ "upstream-freebsd/lib/msun/src/s_llrint.c",
+ "upstream-freebsd/lib/msun/src/s_llrintf.c",
+ "upstream-freebsd/lib/msun/src/s_lrint.c",
+ "upstream-freebsd/lib/msun/src/s_lrintf.c",
+ ],
+ version_script: ":libm.riscv64.map",
+ },
+
x86: {
srcs: [
"i387/fenv.c",
@@ -386,8 +396,6 @@
"upstream-freebsd/lib/msun/src/e_hypot.c",
"upstream-freebsd/lib/msun/src/e_log10.c",
"upstream-freebsd/lib/msun/src/e_sinh.c",
- "upstream-freebsd/lib/msun/src/e_sqrt.c",
- "upstream-freebsd/lib/msun/src/e_sqrtf.c",
"upstream-freebsd/lib/msun/src/s_atan.c",
"upstream-freebsd/lib/msun/src/s_cbrt.c",
"upstream-freebsd/lib/msun/src/s_ceil.c",
@@ -452,8 +460,6 @@
"upstream-freebsd/lib/msun/src/e_hypot.c",
"upstream-freebsd/lib/msun/src/e_log10.c",
"upstream-freebsd/lib/msun/src/e_sinh.c",
- "upstream-freebsd/lib/msun/src/e_sqrt.c",
- "upstream-freebsd/lib/msun/src/e_sqrtf.c",
"upstream-freebsd/lib/msun/src/s_atan.c",
"upstream-freebsd/lib/msun/src/s_cbrt.c",
"upstream-freebsd/lib/msun/src/s_ceil.c",
@@ -560,30 +566,38 @@
name: "libm.arm.map",
out: ["libm.arm.map"],
srcs: ["libm.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) arm $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) arm $(in) $(out)",
}
genrule {
name: "libm.arm64.map",
out: ["libm.arm64.map"],
srcs: ["libm.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) arm64 $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) arm64 $(in) $(out)",
+}
+
+genrule {
+ name: "libm.riscv64.map",
+ out: ["libm.riscv64.map"],
+ srcs: ["libm.map.txt"],
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
}
genrule {
name: "libm.x86.map",
out: ["libm.x86.map"],
srcs: ["libm.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) x86 $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) x86 $(in) $(out)",
}
genrule {
name: "libm.x86_64.map",
out: ["libm.x86_64.map"],
srcs: ["libm.map.txt"],
- tool_files: [":bionic-generate-version-script"],
- cmd: "$(location :bionic-generate-version-script) x86_64 $(in) $(out)",
+ tools: ["generate-version-script"],
+ cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
}
diff --git a/libm/NOTICE b/libm/NOTICE
index 64d253a..bce49ad 100644
--- a/libm/NOTICE
+++ b/libm/NOTICE
@@ -309,6 +309,34 @@
-------------------------------------------------------------------
+Copyright (C) 2022 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
Copyright (c) 1985, 1993
The Regents of the University of California. All rights reserved.
diff --git a/libm/arm64/fenv.c b/libm/arm64/fenv.c
index a99288b..0f28d0c 100644
--- a/libm/arm64/fenv.c
+++ b/libm/arm64/fenv.c
@@ -59,7 +59,6 @@
int fesetenv(const fenv_t* envp) {
fpu_control_t fpcr;
-
__get_fpcr(fpcr);
if (envp->__control != fpcr) {
__set_fpcr(envp->__control);
@@ -70,27 +69,22 @@
int feclearexcept(int excepts) {
fpu_status_t fpsr;
-
- excepts &= FE_ALL_EXCEPT;
__get_fpsr(fpsr);
- fpsr &= ~excepts;
+ fpsr &= ~(excepts & FE_ALL_EXCEPT);
__set_fpsr(fpsr);
return 0;
}
int fegetexceptflag(fexcept_t* flagp, int excepts) {
fpu_status_t fpsr;
-
- excepts &= FE_ALL_EXCEPT;
__get_fpsr(fpsr);
- *flagp = fpsr & excepts;
+ *flagp = fpsr & (excepts & FE_ALL_EXCEPT);
return 0;
}
int fesetexceptflag(const fexcept_t* flagp, int excepts) {
- fpu_status_t fpsr;
-
excepts &= FE_ALL_EXCEPT;
+ fpu_status_t fpsr;
__get_fpsr(fpsr);
fpsr &= ~excepts;
fpsr |= *flagp & excepts;
@@ -100,32 +94,27 @@
int feraiseexcept(int excepts) {
fexcept_t ex = excepts;
-
fesetexceptflag(&ex, excepts);
return 0;
}
int fetestexcept(int excepts) {
fpu_status_t fpsr;
-
- excepts &= FE_ALL_EXCEPT;
__get_fpsr(fpsr);
- return (fpsr & excepts);
+ return (fpsr & (excepts & FE_ALL_EXCEPT));
}
int fegetround(void) {
fpu_control_t fpcr;
-
__get_fpcr(fpcr);
return ((fpcr >> FPCR_RMODE_SHIFT) & FE_TOWARDZERO);
}
int fesetround(int round) {
- fpu_control_t fpcr, new_fpcr;
-
- round &= FE_TOWARDZERO;
+ if (round < FE_TONEAREST || round > FE_TOWARDZERO) return -1;
+ fpu_control_t fpcr;
__get_fpcr(fpcr);
- new_fpcr = fpcr & ~(FE_TOWARDZERO << FPCR_RMODE_SHIFT);
+ fpu_control_t new_fpcr = fpcr & ~(FE_TOWARDZERO << FPCR_RMODE_SHIFT);
new_fpcr |= (round << FPCR_RMODE_SHIFT);
if (new_fpcr != fpcr) {
__set_fpcr(new_fpcr);
@@ -134,33 +123,15 @@
}
int feholdexcept(fenv_t* envp) {
- fpu_status_t fpsr;
- __get_fpsr(fpsr);
- fpu_control_t fpcr;
- __get_fpcr(fpcr);
- fenv_t env = { .__status = fpsr, .__control = fpcr };
- *envp = env;
-
- // Clear all exceptions.
- fpsr &= ~FE_ALL_EXCEPT;
- __set_fpsr(fpsr);
+ fegetenv(envp);
+ feclearexcept(FE_ALL_EXCEPT);
return 0;
}
int feupdateenv(const fenv_t* envp) {
- fpu_status_t fpsr;
- fpu_control_t fpcr;
-
- // Set FPU Control register.
- __get_fpcr(fpcr);
- if (envp->__control != fpcr) {
- __set_fpcr(envp->__control);
- }
-
- // Set FPU Status register to status | currently raised exceptions.
- __get_fpsr(fpsr);
- fpsr = envp->__status | (fpsr & FE_ALL_EXCEPT);
- __set_fpsr(fpsr);
+ int excepts = fetestexcept(FE_ALL_EXCEPT);
+ fesetenv(envp);
+ feraiseexcept(excepts);
return 0;
}
diff --git a/libm/builtins.cpp b/libm/builtins.cpp
index 3b9228c..7487323 100644
--- a/libm/builtins.cpp
+++ b/libm/builtins.cpp
@@ -49,6 +49,9 @@
float ceilf(float x) { return __builtin_ceilf(x); }
double ceil(double x) { return __builtin_ceil(x); }
+double copysign(double x, double y) { return __builtin_copysign(x, y); }
+float copysignf(float x, float y) { return __builtin_copysignf(x, y); }
+
float floorf(float x) { return __builtin_floorf(x); }
double floor(double x) { return __builtin_floor(x); }
@@ -61,6 +64,11 @@
float fminf(float x, float y) { return __builtin_fminf(x, y); }
double fmin(double x, double y) { return __builtin_fmin(x, y); }
+long lround(double x) { return __builtin_lround(x); }
+long lroundf(float x) { return __builtin_lroundf(x); }
+long long llround(double x) { return __builtin_llround(x); }
+long long llroundf(float x) { return __builtin_llroundf(x); }
+
float rintf(float x) { return __builtin_rintf(x); }
double rint(double x) { return __builtin_rint(x); }
diff --git a/libm/riscv64/fenv.c b/libm/riscv64/fenv.c
new file mode 100644
index 0000000..f16e5a9
--- /dev/null
+++ b/libm/riscv64/fenv.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <fenv.h>
+#include <stdint.h>
+
+const fenv_t __fe_dfl_env = 0;
+
+int fegetenv(fenv_t* envp) {
+ __asm__ __volatile__("frcsr %0" : "=r"(*envp));
+ return 0;
+}
+
+int fesetenv(const fenv_t* envp) {
+ fenv_t env;
+ fegetenv(&env);
+ if (*envp != env) {
+ __asm__ __volatile__("fscsr %z0" : : "r"(*envp));
+ }
+ return 0;
+}
+
+int feclearexcept(int excepts) {
+ __asm__ __volatile__("csrc fflags, %0" : : "r"(excepts & FE_ALL_EXCEPT));
+ return 0;
+}
+
+int fegetexceptflag(fexcept_t* flagp, int excepts) {
+ *flagp = fetestexcept(excepts & FE_ALL_EXCEPT);
+ return 0;
+}
+
+int fesetexceptflag(const fexcept_t* flagp, int excepts) {
+ feclearexcept((~*flagp) & excepts);
+ feraiseexcept(*flagp & excepts);
+ return 0;
+}
+
+int feraiseexcept(int excepts) {
+ __asm__ __volatile__("csrs fflags, %0" : : "r"(excepts));
+ return 0;
+}
+
+int fetestexcept(int excepts) {
+ int flags;
+ __asm__ __volatile__("frflags %0" : "=r"(flags));
+ return flags & excepts;
+}
+
+int fegetround(void) {
+ int rm;
+ __asm__ __volatile__("frrm %0" : "=r"(rm));
+ return rm;
+}
+
+int fesetround(int round) {
+ if (round < FE_TONEAREST || round > FE_UPWARD) return -1;
+ __asm__ __volatile__("fsrm %z0" : : "r"(round));
+ return 0;
+}
+
+int feholdexcept(fenv_t* envp) {
+ fegetenv(envp);
+ feclearexcept(FE_ALL_EXCEPT);
+ return 0;
+}
+
+int feupdateenv(const fenv_t* envp) {
+ int excepts = fetestexcept(FE_ALL_EXCEPT);
+ fesetenv(envp);
+ feraiseexcept(excepts);
+ return 0;
+}
+
+int feenableexcept(int mask __unused) {
+ return -1;
+}
+
+int fedisableexcept(int mask __unused) {
+ return 0;
+}
+
+int fegetexcept(void) {
+ return 0;
+}
diff --git a/libm/riscv64/lrint.S b/libm/riscv64/lrint.S
new file mode 100644
index 0000000..eb13833
--- /dev/null
+++ b/libm/riscv64/lrint.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+
+ENTRY(lrint)
+ fcvt.l.d a0, fa0, dyn
+ ret
+END(lrint)
+
+ENTRY(lrintf)
+ fcvt.l.s a0, fa0, dyn
+ ret
+END(lrintf)
+
+// sizeof(long) and sizeof(long long) are the same for riscv64
+ALIAS_SYMBOL(llrint, lrint);
+
+ALIAS_SYMBOL(llrintf, lrintf);
diff --git a/libm/riscv64/sqrt.S b/libm/riscv64/sqrt.S
new file mode 100644
index 0000000..0db1335
--- /dev/null
+++ b/libm/riscv64/sqrt.S
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+
+ENTRY(sqrt)
+ fsqrt.d fa0, fa0
+ ret
+END(sqrt)
+
+ENTRY(sqrtf)
+ fsqrt.s fa0, fa0
+ ret
+END(sqrtf)
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sqrt.c b/libm/upstream-freebsd/lib/msun/src/e_sqrt.c
deleted file mode 100644
index 37351a4..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_sqrt.c
+++ /dev/null
@@ -1,459 +0,0 @@
-
-/* @(#)e_sqrt.c 1.3 95/01/18 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <float.h>
-
-#include "math.h"
-#include "math_private.h"
-
-#ifdef USE_BUILTIN_SQRT
-double
-__ieee754_sqrt(double x)
-{
- return (__builtin_sqrt(x));
-}
-#else
-/* __ieee754_sqrt(x)
- * Return correctly rounded sqrt.
- * ------------------------------------------
- * | Use the hardware sqrt if you have one |
- * ------------------------------------------
- * Method:
- * Bit by bit method using integer arithmetic. (Slow, but portable)
- * 1. Normalization
- * Scale x to y in [1,4) with even powers of 2:
- * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
- * sqrt(x) = 2^k * sqrt(y)
- * 2. Bit by bit computation
- * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
- * i 0
- * i+1 2
- * s = 2*q , and y = 2 * ( y - q ). (1)
- * i i i i
- *
- * To compute q from q , one checks whether
- * i+1 i
- *
- * -(i+1) 2
- * (q + 2 ) <= y. (2)
- * i
- * -(i+1)
- * If (2) is false, then q = q ; otherwise q = q + 2 .
- * i+1 i i+1 i
- *
- * With some algebric manipulation, it is not difficult to see
- * that (2) is equivalent to
- * -(i+1)
- * s + 2 <= y (3)
- * i i
- *
- * The advantage of (3) is that s and y can be computed by
- * i i
- * the following recurrence formula:
- * if (3) is false
- *
- * s = s , y = y ; (4)
- * i+1 i i+1 i
- *
- * otherwise,
- * -i -(i+1)
- * s = s + 2 , y = y - s - 2 (5)
- * i+1 i i+1 i i
- *
- * One may easily use induction to prove (4) and (5).
- * Note. Since the left hand side of (3) contain only i+2 bits,
- * it does not necessary to do a full (53-bit) comparison
- * in (3).
- * 3. Final rounding
- * After generating the 53 bits result, we compute one more bit.
- * Together with the remainder, we can decide whether the
- * result is exact, bigger than 1/2ulp, or less than 1/2ulp
- * (it will never equal to 1/2ulp).
- * The rounding mode can be detected by checking whether
- * huge + tiny is equal to huge, and whether huge - tiny is
- * equal to huge for some floating point number "huge" and "tiny".
- *
- * Special cases:
- * sqrt(+-0) = +-0 ... exact
- * sqrt(inf) = inf
- * sqrt(-ve) = NaN ... with invalid signal
- * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
- *
- * Other methods : see the appended file at the end of the program below.
- *---------------
- */
-
-static const double one = 1.0, tiny=1.0e-300;
-
-double
-__ieee754_sqrt(double x)
-{
- double z;
- int32_t sign = (int)0x80000000;
- int32_t ix0,s0,q,m,t,i;
- u_int32_t r,t1,s1,ix1,q1;
-
- EXTRACT_WORDS(ix0,ix1,x);
-
- /* take care of Inf and NaN */
- if((ix0&0x7ff00000)==0x7ff00000) {
- return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
- sqrt(-inf)=sNaN */
- }
- /* take care of zero */
- if(ix0<=0) {
- if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
- else if(ix0<0)
- return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
- }
- /* normalize x */
- m = (ix0>>20);
- if(m==0) { /* subnormal x */
- while(ix0==0) {
- m -= 21;
- ix0 |= (ix1>>11); ix1 <<= 21;
- }
- for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
- m -= i-1;
- ix0 |= (ix1>>(32-i));
- ix1 <<= i;
- }
- m -= 1023; /* unbias exponent */
- ix0 = (ix0&0x000fffff)|0x00100000;
- if(m&1){ /* odd m, double x to make it even */
- ix0 += ix0 + ((ix1&sign)>>31);
- ix1 += ix1;
- }
- m >>= 1; /* m = [m/2] */
-
- /* generate sqrt(x) bit by bit */
- ix0 += ix0 + ((ix1&sign)>>31);
- ix1 += ix1;
- q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
- r = 0x00200000; /* r = moving bit from right to left */
-
- while(r!=0) {
- t = s0+r;
- if(t<=ix0) {
- s0 = t+r;
- ix0 -= t;
- q += r;
- }
- ix0 += ix0 + ((ix1&sign)>>31);
- ix1 += ix1;
- r>>=1;
- }
-
- r = sign;
- while(r!=0) {
- t1 = s1+r;
- t = s0;
- if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
- s1 = t1+r;
- if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
- ix0 -= t;
- if (ix1 < t1) ix0 -= 1;
- ix1 -= t1;
- q1 += r;
- }
- ix0 += ix0 + ((ix1&sign)>>31);
- ix1 += ix1;
- r>>=1;
- }
-
- /* use floating add to find out rounding direction */
- if((ix0|ix1)!=0) {
- z = one-tiny; /* trigger inexact flag */
- if (z>=one) {
- z = one+tiny;
- if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;}
- else if (z>one) {
- if (q1==(u_int32_t)0xfffffffe) q+=1;
- q1+=2;
- } else
- q1 += (q1&1);
- }
- }
- ix0 = (q>>1)+0x3fe00000;
- ix1 = q1>>1;
- if ((q&1)==1) ix1 |= sign;
- ix0 += (m <<20);
- INSERT_WORDS(z,ix0,ix1);
- return z;
-}
-#endif
-
-#if (LDBL_MANT_DIG == 53)
-__weak_reference(sqrt, sqrtl);
-#endif
-
-/*
-Other methods (use floating-point arithmetic)
--------------
-(This is a copy of a drafted paper by Prof W. Kahan
-and K.C. Ng, written in May, 1986)
-
- Two algorithms are given here to implement sqrt(x)
- (IEEE double precision arithmetic) in software.
- Both supply sqrt(x) correctly rounded. The first algorithm (in
- Section A) uses newton iterations and involves four divisions.
- The second one uses reciproot iterations to avoid division, but
- requires more multiplications. Both algorithms need the ability
- to chop results of arithmetic operations instead of round them,
- and the INEXACT flag to indicate when an arithmetic operation
- is executed exactly with no roundoff error, all part of the
- standard (IEEE 754-1985). The ability to perform shift, add,
- subtract and logical AND operations upon 32-bit words is needed
- too, though not part of the standard.
-
-A. sqrt(x) by Newton Iteration
-
- (1) Initial approximation
-
- Let x0 and x1 be the leading and the trailing 32-bit words of
- a floating point number x (in IEEE double format) respectively
-
- 1 11 52 ...widths
- ------------------------------------------------------
- x: |s| e | f |
- ------------------------------------------------------
- msb lsb msb lsb ...order
-
-
- ------------------------ ------------------------
- x0: |s| e | f1 | x1: | f2 |
- ------------------------ ------------------------
-
- By performing shifts and subtracts on x0 and x1 (both regarded
- as integers), we obtain an 8-bit approximation of sqrt(x) as
- follows.
-
- k := (x0>>1) + 0x1ff80000;
- y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
- Here k is a 32-bit integer and T1[] is an integer array containing
- correction terms. Now magically the floating value of y (y's
- leading 32-bit word is y0, the value of its trailing word is 0)
- approximates sqrt(x) to almost 8-bit.
-
- Value of T1:
- static int T1[32]= {
- 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
- 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
- 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
- 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
-
- (2) Iterative refinement
-
- Apply Heron's rule three times to y, we have y approximates
- sqrt(x) to within 1 ulp (Unit in the Last Place):
-
- y := (y+x/y)/2 ... almost 17 sig. bits
- y := (y+x/y)/2 ... almost 35 sig. bits
- y := y-(y-x/y)/2 ... within 1 ulp
-
-
- Remark 1.
- Another way to improve y to within 1 ulp is:
-
- y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
- y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
-
- 2
- (x-y )*y
- y := y + 2* ---------- ...within 1 ulp
- 2
- 3y + x
-
-
- This formula has one division fewer than the one above; however,
- it requires more multiplications and additions. Also x must be
- scaled in advance to avoid spurious overflow in evaluating the
- expression 3y*y+x. Hence it is not recommended uless division
- is slow. If division is very slow, then one should use the
- reciproot algorithm given in section B.
-
- (3) Final adjustment
-
- By twiddling y's last bit it is possible to force y to be
- correctly rounded according to the prevailing rounding mode
- as follows. Let r and i be copies of the rounding mode and
- inexact flag before entering the square root program. Also we
- use the expression y+-ulp for the next representable floating
- numbers (up and down) of y. Note that y+-ulp = either fixed
- point y+-1, or multiply y by nextafter(1,+-inf) in chopped
- mode.
-
- I := FALSE; ... reset INEXACT flag I
- R := RZ; ... set rounding mode to round-toward-zero
- z := x/y; ... chopped quotient, possibly inexact
- If(not I) then { ... if the quotient is exact
- if(z=y) {
- I := i; ... restore inexact flag
- R := r; ... restore rounded mode
- return sqrt(x):=y.
- } else {
- z := z - ulp; ... special rounding
- }
- }
- i := TRUE; ... sqrt(x) is inexact
- If (r=RN) then z=z+ulp ... rounded-to-nearest
- If (r=RP) then { ... round-toward-+inf
- y = y+ulp; z=z+ulp;
- }
- y := y+z; ... chopped sum
- y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
- I := i; ... restore inexact flag
- R := r; ... restore rounded mode
- return sqrt(x):=y.
-
- (4) Special cases
-
- Square root of +inf, +-0, or NaN is itself;
- Square root of a negative number is NaN with invalid signal.
-
-
-B. sqrt(x) by Reciproot Iteration
-
- (1) Initial approximation
-
- Let x0 and x1 be the leading and the trailing 32-bit words of
- a floating point number x (in IEEE double format) respectively
- (see section A). By performing shifs and subtracts on x0 and y0,
- we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
-
- k := 0x5fe80000 - (x0>>1);
- y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits
-
- Here k is a 32-bit integer and T2[] is an integer array
- containing correction terms. Now magically the floating
- value of y (y's leading 32-bit word is y0, the value of
- its trailing word y1 is set to zero) approximates 1/sqrt(x)
- to almost 7.8-bit.
-
- Value of T2:
- static int T2[64]= {
- 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
- 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
- 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
- 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
- 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
- 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
- 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
- 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
-
- (2) Iterative refinement
-
- Apply Reciproot iteration three times to y and multiply the
- result by x to get an approximation z that matches sqrt(x)
- to about 1 ulp. To be exact, we will have
- -1ulp < sqrt(x)-z<1.0625ulp.
-
- ... set rounding mode to Round-to-nearest
- y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x)
- y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
- ... special arrangement for better accuracy
- z := x*y ... 29 bits to sqrt(x), with z*y<1
- z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x)
-
- Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
- (a) the term z*y in the final iteration is always less than 1;
- (b) the error in the final result is biased upward so that
- -1 ulp < sqrt(x) - z < 1.0625 ulp
- instead of |sqrt(x)-z|<1.03125ulp.
-
- (3) Final adjustment
-
- By twiddling y's last bit it is possible to force y to be
- correctly rounded according to the prevailing rounding mode
- as follows. Let r and i be copies of the rounding mode and
- inexact flag before entering the square root program. Also we
- use the expression y+-ulp for the next representable floating
- numbers (up and down) of y. Note that y+-ulp = either fixed
- point y+-1, or multiply y by nextafter(1,+-inf) in chopped
- mode.
-
- R := RZ; ... set rounding mode to round-toward-zero
- switch(r) {
- case RN: ... round-to-nearest
- if(x<= z*(z-ulp)...chopped) z = z - ulp; else
- if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
- break;
- case RZ:case RM: ... round-to-zero or round-to--inf
- R:=RP; ... reset rounding mod to round-to-+inf
- if(x<z*z ... rounded up) z = z - ulp; else
- if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
- break;
- case RP: ... round-to-+inf
- if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
- if(x>z*z ...chopped) z = z+ulp;
- break;
- }
-
- Remark 3. The above comparisons can be done in fixed point. For
- example, to compare x and w=z*z chopped, it suffices to compare
- x1 and w1 (the trailing parts of x and w), regarding them as
- two's complement integers.
-
- ...Is z an exact square root?
- To determine whether z is an exact square root of x, let z1 be the
- trailing part of z, and also let x0 and x1 be the leading and
- trailing parts of x.
-
- If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
- I := 1; ... Raise Inexact flag: z is not exact
- else {
- j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2
- k := z1 >> 26; ... get z's 25-th and 26-th
- fraction bits
- I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
- }
- R:= r ... restore rounded mode
- return sqrt(x):=z.
-
- If multiplication is cheaper then the foregoing red tape, the
- Inexact flag can be evaluated by
-
- I := i;
- I := (z*z!=x) or I.
-
- Note that z*z can overwrite I; this value must be sensed if it is
- True.
-
- Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
- zero.
-
- --------------------
- z1: | f2 |
- --------------------
- bit 31 bit 0
-
- Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
- or even of logb(x) have the following relations:
-
- -------------------------------------------------
- bit 27,26 of z1 bit 1,0 of x1 logb(x)
- -------------------------------------------------
- 00 00 odd and even
- 01 01 even
- 10 10 odd
- 10 00 even
- 11 01 even
- -------------------------------------------------
-
- (4) Special cases (see (4) of Section A).
-
- */
-
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sqrtf.c b/libm/upstream-freebsd/lib/msun/src/e_sqrtf.c
deleted file mode 100644
index 06e5d62..0000000
--- a/libm/upstream-freebsd/lib/msun/src/e_sqrtf.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* e_sqrtf.c -- float version of e_sqrt.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#ifndef lint
-static char rcsid[] = "$FreeBSD$";
-#endif
-
-#include "math.h"
-#include "math_private.h"
-
-#ifdef USE_BUILTIN_SQRTF
-float
-__ieee754_sqrtf(float x)
-{
- return (__builtin_sqrtf(x));
-}
-#else
-static const float one = 1.0, tiny=1.0e-30;
-
-float
-__ieee754_sqrtf(float x)
-{
- float z;
- int32_t sign = (int)0x80000000;
- int32_t ix,s,q,m,t,i;
- u_int32_t r;
-
- GET_FLOAT_WORD(ix,x);
-
- /* take care of Inf and NaN */
- if((ix&0x7f800000)==0x7f800000) {
- return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
- sqrt(-inf)=sNaN */
- }
- /* take care of zero */
- if(ix<=0) {
- if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
- else if(ix<0)
- return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
- }
- /* normalize x */
- m = (ix>>23);
- if(m==0) { /* subnormal x */
- for(i=0;(ix&0x00800000)==0;i++) ix<<=1;
- m -= i-1;
- }
- m -= 127; /* unbias exponent */
- ix = (ix&0x007fffff)|0x00800000;
- if(m&1) /* odd m, double x to make it even */
- ix += ix;
- m >>= 1; /* m = [m/2] */
-
- /* generate sqrt(x) bit by bit */
- ix += ix;
- q = s = 0; /* q = sqrt(x) */
- r = 0x01000000; /* r = moving bit from right to left */
-
- while(r!=0) {
- t = s+r;
- if(t<=ix) {
- s = t+r;
- ix -= t;
- q += r;
- }
- ix += ix;
- r>>=1;
- }
-
- /* use floating add to find out rounding direction */
- if(ix!=0) {
- z = one-tiny; /* trigger inexact flag */
- if (z>=one) {
- z = one+tiny;
- if (z>one)
- q += 2;
- else
- q += (q&1);
- }
- }
- ix = (q>>1)+0x3f000000;
- ix += (m <<23);
- SET_FLOAT_WORD(z,ix);
- return z;
-}
-#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/math_private.h b/libm/upstream-freebsd/lib/msun/src/math_private.h
index b91b54c..df526e7 100644
--- a/libm/upstream-freebsd/lib/msun/src/math_private.h
+++ b/libm/upstream-freebsd/lib/msun/src/math_private.h
@@ -460,7 +460,7 @@
* or by having |c| a few percent smaller than |a|. Pre-normalization of
* (a, b) may help.
*
- * This is is a variant of an algorithm of Kahan (see Knuth (1981) 4.2.2
+ * This is a variant of an algorithm of Kahan (see Knuth (1981) 4.2.2
* exercise 19). We gain considerable efficiency by requiring the terms to
* be sufficiently normalized and sufficiently increasing.
*/
@@ -644,7 +644,7 @@
* return type provided their arg is a floating point integer. They can
* sometimes be more efficient because no rounding is required.
*/
-#if (defined(amd64) || defined(__i386__)) && defined(__GNUCLIKE_ASM)
+#if defined(amd64) || defined(__i386__)
#define irint(x) \
(sizeof(x) == sizeof(float) && \
sizeof(__float_t) == sizeof(long double) ? irintf(x) : \
@@ -657,7 +657,7 @@
#define i64rint(x) ((int64_t)(x)) /* only needed for ld128 so not opt. */
-#if defined(__i386__) && defined(__GNUCLIKE_ASM)
+#if defined(__i386__)
static __inline int
irintf(float x)
{
@@ -677,7 +677,7 @@
}
#endif
-#if (defined(__amd64__) || defined(__i386__)) && defined(__GNUCLIKE_ASM)
+#if defined(__amd64__) || defined(__i386__)
static __inline int
irintl(long double x)
{
diff --git a/libm/upstream-freebsd/lib/msun/src/w_cabsf.c b/libm/upstream-freebsd/lib/msun/src/w_cabsf.c
index e7bfe22..b5065c8 100644
--- a/libm/upstream-freebsd/lib/msun/src/w_cabsf.c
+++ b/libm/upstream-freebsd/lib/msun/src/w_cabsf.c
@@ -15,8 +15,7 @@
#include "math_private.h"
float
-cabsf(z)
- float complex z;
+cabsf(float complex z)
{
return hypotf(crealf(z), cimagf(z));
diff --git a/libm/upstream-freebsd/lib/msun/src/w_drem.c b/libm/upstream-freebsd/lib/msun/src/w_drem.c
index 0f68409..74008a5 100644
--- a/libm/upstream-freebsd/lib/msun/src/w_drem.c
+++ b/libm/upstream-freebsd/lib/msun/src/w_drem.c
@@ -8,8 +8,7 @@
#include <math.h>
double
-drem(x, y)
- double x, y;
+drem(double x, double y)
{
return remainder(x, y);
}
diff --git a/linker/Android.bp b/linker/Android.bp
index d5e7367..83077c6 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -52,6 +52,9 @@
arm64: {
srcs: ["arch/arm64/linker_wrapper_begin.S"],
},
+ riscv64: {
+ srcs: ["arch/riscv64/linker_wrapper_begin.S"],
+ },
x86_64: {
srcs: ["arch/x86_64/linker_wrapper_begin.S"],
},
@@ -115,7 +118,7 @@
"libasync_safe",
- "liblog",
+ "liblog_for_runtime_apex",
],
// We need to access Bionic private headers in the linker.
@@ -208,6 +211,13 @@
}
filegroup {
+ name: "linker_sources_riscv64",
+ srcs: [
+ "arch/riscv64/begin.S",
+ ],
+}
+
+filegroup {
name: "linker_sources_x86",
srcs: [
"arch/x86/begin.S",
@@ -224,10 +234,11 @@
cc_defaults {
name: "linker_version_script_overlay",
arch: {
- arm: { version_script: "linker.arm.map" },
- arm64: { version_script: "linker.generic.map" },
- x86: { version_script: "linker.generic.map" },
- x86_64: { version_script: "linker.generic.map" },
+ arm: { version_script: "linker.arm.map" },
+ arm64: { version_script: "linker.generic.map" },
+ riscv64: { version_script: "linker.generic.map" },
+ x86: { version_script: "linker.generic.map" },
+ x86_64: { version_script: "linker.generic.map" },
},
}
@@ -241,15 +252,50 @@
arch: {
arm: {
srcs: [":linker_sources_arm"],
+
+ // Arm 32 bit does not produce complete exidx unwind information
+ // so keep the .debug_frame which is relatively small and does
+ // include needed unwind information.
+ // See b/242162222 for details.
+ strip: {
+ keep_symbols_and_debug_frame: true,
+ },
},
arm64: {
srcs: [":linker_sources_arm64"],
+
+ // Leave the symbols in the shared library so that stack unwinders can produce
+ // meaningful name resolution.
+ strip: {
+ keep_symbols: true,
+ },
+ },
+ riscv64: {
+ srcs: [":linker_sources_riscv64"],
+
+ // Leave the symbols in the shared library so that stack unwinders can produce
+ // meaningful name resolution.
+ strip: {
+ keep_symbols: true,
+ },
},
x86: {
srcs: [":linker_sources_x86"],
+
+ // Leave the symbols in the shared library so that stack unwinders can produce
+ // meaningful name resolution.
+ strip: {
+ keep_symbols: true,
+ },
},
x86_64: {
srcs: [":linker_sources_x86_64"],
+
+ // Leave the symbols in the shared library so that stack unwinders can produce
+ // meaningful name resolution.
+ strip: {
+ keep_symbols: true,
+ },
},
},
@@ -275,12 +321,6 @@
static_executable: true,
- // Leave the symbols in the shared library so that stack unwinders can produce
- // meaningful name resolution.
- strip: {
- keep_symbols: true,
- },
-
// Insert an extra objcopy step to add prefix to symbols. This is needed to prevent gdb
// looking up symbols in the linker by mistake.
prefix_symbols: "__dl_",
@@ -406,6 +446,7 @@
"-Wl,--exclude-libs=libgcc_stripped.a",
"-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
"-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
+ "-Wl,--exclude-libs=libclang_rt.builtins-riscv64-android.a",
"-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
"-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
],
@@ -494,7 +535,7 @@
static_libs: [
"libasync_safe",
"libbase",
- "liblog",
+ "liblog_for_runtime_apex",
],
arch: {
diff --git a/linker/NOTICE b/linker/NOTICE
index 8f70d87..d61a193 100644
--- a/linker/NOTICE
+++ b/linker/NOTICE
@@ -334,3 +334,31 @@
-------------------------------------------------------------------
+Copyright (C) 2022 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
diff --git a/linker/arch/arm/begin.S b/linker/arch/arm/begin.S
index 80d9fe1..3b673f0 100644
--- a/linker/arch/arm/begin.S
+++ b/linker/arch/arm/begin.S
@@ -35,6 +35,6 @@
mov r0, sp
bl __linker_init
- /* linker init returns the _entry address in the main image */
+ // __linker_init returns the address of the entry point in the main image.
bx r0
END(_start)
diff --git a/linker/arch/arm64/begin.S b/linker/arch/arm64/begin.S
index a947475..14999cd 100644
--- a/linker/arch/arm64/begin.S
+++ b/linker/arch/arm64/begin.S
@@ -35,6 +35,6 @@
mov x0, sp
bl __linker_init
- /* linker init returns the _entry address in the main image */
+ // __linker_init returns the address of the entry point in the main image.
br x0
END(_start)
diff --git a/linker/arch/riscv64/begin.S b/linker/arch/riscv64/begin.S
new file mode 100644
index 0000000..f7509c6
--- /dev/null
+++ b/linker/arch/riscv64/begin.S
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <private/bionic_asm.h>
+
+ENTRY(_start)
+ // Force unwinds to end in this function.
+ .cfi_undefined ra
+
+ mv a0, sp
+ jal __linker_init
+
+ // __linker_init returns the address of the entry point in the main image.
+ jr a0
+END(_start)
diff --git a/linker/arch/x86/begin.S b/linker/arch/x86/begin.S
index 3812646..81e2740 100644
--- a/linker/arch/x86/begin.S
+++ b/linker/arch/x86/begin.S
@@ -38,6 +38,6 @@
call __linker_init // %esp is aligned to 16 before the call.
addl $16, %esp
- /* linker init returns (%eax) the _entry address in the main image */
+ // __linker_init returns the address of the entry point in the main image.
jmp *%eax
END(_start)
diff --git a/linker/arch/x86_64/begin.S b/linker/arch/x86_64/begin.S
index 4722301..baba0db 100644
--- a/linker/arch/x86_64/begin.S
+++ b/linker/arch/x86_64/begin.S
@@ -35,6 +35,6 @@
mov %rsp, %rdi
call __linker_init
- /* linker init returns (%rax) the _entry address in the main image */
+ // __linker_init returns the address of the entry point in the main image.
jmp *%rax
END(_start)
diff --git a/linker/linker.cpp b/linker/linker.cpp
index c6588d2..9779c8d 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -371,7 +371,7 @@
char* static_tls = reinterpret_cast<char*>(__get_bionic_tcb()) - layout.offset_bionic_tcb();
return static_tls + tls_mod.static_offset;
} else if (should_alloc) {
- const TlsIndex ti { si_tls->module_id, 0 };
+ const TlsIndex ti { si_tls->module_id, static_cast<size_t>(0 - TLS_DTV_OFFSET) };
return TLS_GET_ADDR(&ti);
} else {
TlsDtv* dtv = __get_tcb_dtv(__get_bionic_tcb());
@@ -1568,18 +1568,16 @@
task->set_extinfo(is_dt_needed ? nullptr : extinfo);
task->set_dt_needed(is_dt_needed);
- LD_LOG(kLogDlopen, "find_libraries(ns=%s): task=%s, is_dt_needed=%d", ns->get_name(),
- task->get_name(), is_dt_needed);
-
// Note: start from the namespace that is stored in the LoadTask. This namespace
// is different from the current namespace when the LoadTask is for a transitive
// dependency and the lib that created the LoadTask is not found in the
- // 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,
- rtld_flags)) {
+ // current namespace but in one of the linked namespaces.
+ android_namespace_t* start_ns = const_cast<android_namespace_t*>(task->get_start_from());
+
+ LD_LOG(kLogDlopen, "find_library_internal(ns=%s@%p): task=%s, is_dt_needed=%d",
+ start_ns->get_name(), start_ns, task->get_name(), is_dt_needed);
+
+ if (!find_library_internal(start_ns, task, &zip_archive_cache, &load_tasks, rtld_flags)) {
return false;
}
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 9e5be34..f0e7b1b 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -68,7 +68,8 @@
static void set_bss_vma_name(soinfo* si);
-void __libc_init_mte(const void* phdr_start, size_t phdr_count, uintptr_t load_bias);
+void __libc_init_mte(const void* phdr_start, size_t phdr_count, uintptr_t load_bias,
+ void* stack_top);
// These should be preserved static to avoid emitting
// RELATIVE relocations for the part of the code running
@@ -408,7 +409,7 @@
}
}
- __libc_init_mte(somain->phdr, somain->phnum, somain->load_bias);
+ __libc_init_mte(somain->phdr, somain->phnum, somain->load_bias, args.argv);
#endif
// Register the main executable and the linker upfront to have
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 60fd776..aa1a208 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -51,6 +51,8 @@
return EM_AARCH64;
#elif defined(__i386__)
return EM_386;
+#elif defined(__riscv)
+ return EM_RISCV;
#elif defined(__x86_64__)
return EM_X86_64;
#endif
diff --git a/linker/linker_relocate.cpp b/linker/linker_relocate.cpp
index c7c7bfb..952dade 100644
--- a/linker/linker_relocate.cpp
+++ b/linker/linker_relocate.cpp
@@ -49,7 +49,9 @@
case R_GENERIC_TLS_DTPMOD:
case R_GENERIC_TLS_DTPREL:
case R_GENERIC_TLS_TPREL:
+#if defined(R_GENERIC_TLSDESC)
case R_GENERIC_TLSDESC:
+#endif
return true;
default:
return false;
@@ -426,7 +428,7 @@
case R_GENERIC_TLS_DTPREL:
count_relocation_if<IsGeneral>(kRelocRelative);
{
- const ElfW(Addr) result = sym_addr + get_addend_rel();
+ const ElfW(Addr) result = sym_addr + get_addend_rel() - TLS_DTV_OFFSET;
trace_reloc("RELO TLS_DTPREL %16p <- %16p %s",
rel_target, reinterpret_cast<void*>(result), sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = result;
diff --git a/linker/linker_relocs.h b/linker/linker_relocs.h
index 93d899e..37a7880 100644
--- a/linker/linker_relocs.h
+++ b/linker/linker_relocs.h
@@ -73,6 +73,20 @@
#define R_GENERIC_TLS_TPREL R_386_TLS_TPOFF
#define R_GENERIC_TLSDESC R_386_TLS_DESC
+#elif defined (__riscv)
+
+#define R_GENERIC_JUMP_SLOT R_RISCV_JUMP_SLOT
+#define R_GENERIC_ABSOLUTE R_RISCV_64
+#define R_GENERIC_GLOB_DAT R_RISCV_64
+#define R_GENERIC_RELATIVE R_RISCV_RELATIVE
+#define R_GENERIC_IRELATIVE R_RISCV_IRELATIVE
+#define R_GENERIC_COPY R_RISCV_COPY
+#define R_GENERIC_TLS_DTPMOD R_RISCV_TLS_DTPMOD64
+#define R_GENERIC_TLS_DTPREL R_RISCV_TLS_DTPREL64
+#define R_GENERIC_TLS_TPREL R_RISCV_TLS_TPREL64
+// TODO: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/94
+// #define R_GENERIC_TLSDESC R_RISCV_TLS_DESC
+
#elif defined (__x86_64__)
#define R_GENERIC_JUMP_SLOT R_X86_64_JUMP_SLOT
diff --git a/linker/linker_transparent_hugepage_support.cpp b/linker/linker_transparent_hugepage_support.cpp
index 65ba4cd..0631577 100644
--- a/linker/linker_transparent_hugepage_support.cpp
+++ b/linker/linker_transparent_hugepage_support.cpp
@@ -39,6 +39,6 @@
return false;
}
return enabled.find("[never]") == std::string::npos;
- };
+ }();
return transparent_hugepages_supported;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index a54ffb8..71be058 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -331,8 +331,8 @@
cc_test_library {
name: "clang_diagnostic_tests",
cflags: [
- "-Xclang",
- "-verify",
+ "-Xclang",
+ "-verify",
],
srcs: ["sys_ioctl_diag_test.cpp"],
}
@@ -393,6 +393,7 @@
"math_test.cpp",
"math_force_long_double_test.cpp",
"membarrier_test.cpp",
+ "memtag_stack_test.cpp",
"mntent_test.cpp",
"mte_test.cpp",
"netdb_test.cpp",
@@ -479,6 +480,7 @@
"uchar_test.cpp",
"unistd_nofortify_test.cpp",
"unistd_test.cpp",
+ "utils.cpp",
"utmp_test.cpp",
"wchar_test.cpp",
"wctype_test.cpp",
@@ -598,18 +600,6 @@
],
}
-cc_test_library {
- name: "libBionicGwpAsanTests",
- defaults: ["bionic_tests_defaults"],
- srcs: [
- "gwp_asan_test.cpp",
- ],
- include_dirs: [
- "bionic/libc",
- ],
- static_libs: ["libbase"],
-}
-
// -----------------------------------------------------------------------------
// Fortify tests.
// -----------------------------------------------------------------------------
@@ -641,9 +631,6 @@
],
tidy: false,
target: {
- host: {
- clang_cflags: ["-D__clang__"],
- },
musl: {
// Musl doesn't have fortify
enabled: false,
@@ -727,7 +714,7 @@
tidy: false,
target: {
host: {
- clang_cflags: ["-D__clang__"],
+ cflags: ["-D__clang__"],
},
},
}
@@ -762,7 +749,6 @@
},
}
-
// -----------------------------------------------------------------------------
// Library of all tests (excluding the dynamic linker tests).
// -----------------------------------------------------------------------------
@@ -774,7 +760,6 @@
"libBionicStandardTests",
"libBionicElfTlsTests",
"libBionicFramePointerTests",
- "libBionicGwpAsanTests",
"libfortify1-tests-clang",
"libfortify1-new-tests-clang",
"libfortify2-tests-clang",
@@ -876,6 +861,7 @@
"__cxa_thread_atexit_test.cpp",
"gtest_globals.cpp",
"gtest_main.cpp",
+ "gwp_asan_test.cpp",
"thread_local_test.cpp",
],
@@ -928,6 +914,8 @@
"heap_tagging_static_disabled_helper",
"heap_tagging_static_sync_helper",
"heap_tagging_sync_helper",
+ "stack_tagging_helper",
+ "stack_tagging_static_helper",
"ld_config_test_helper",
"ld_config_test_helper_lib1",
"ld_config_test_helper_lib2",
@@ -1176,6 +1164,8 @@
"heap_tagging_static_disabled_helper",
"heap_tagging_static_sync_helper",
"heap_tagging_sync_helper",
+ "stack_tagging_helper",
+ "stack_tagging_static_helper",
],
}
diff --git a/tests/NOTICE b/tests/NOTICE
index 8c3483c..167f90b 100644
--- a/tests/NOTICE
+++ b/tests/NOTICE
@@ -383,6 +383,22 @@
-------------------------------------------------------------------
Copyright (C) 2022 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2022 The Android Open Source Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index a61586b..2f3e905 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -32,9 +32,10 @@
#include <regex>
#include <string>
-#include "gtest_globals.h"
#include <android-base/file.h>
+#include <android-base/macros.h>
#include <android-base/test_utils.h>
+#include "gtest_globals.h"
#include "utils.h"
extern "C" int main_global_default_serial() {
@@ -84,22 +85,13 @@
#if defined(__BIONIC__)
#if defined(__LP64__)
- static constexpr const char* kPathToLinker = "/system/bin/linker64";
+#define LINKER_NAME "linker64"
#else
- static constexpr const char* kPathToLinker = "/system/bin/linker";
+#define LINKER_NAME "linker"
#endif
-
-#if defined (__aarch64__)
- static constexpr const char* kAlternatePathToLinker = "/system/bin/arm64/linker64";
-#elif defined (__arm__)
- static constexpr const char* kAlternatePathToLinker = "/system/bin/arm/linker";
-#elif defined (__x86_64__)
- static constexpr const char* kAlternatePathToLinker = "/system/bin/x86_64/linker64";
-#elif defined (__i386__)
- static constexpr const char* kAlternatePathToLinker = "/system/bin/x86/linker";
-#else
-#error "Unknown architecture"
-#endif
+static constexpr const char* kPathToLinker = "/system/bin/" LINKER_NAME;
+static constexpr const char* kAlternatePathToLinker = "/system/bin/" ABI_STRING "/" LINKER_NAME;
+#undef LINKER_NAME
const char* PathToLinker() {
// On the systems with emulated architecture linker would be of different
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 940e726..c5d1218 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -33,6 +33,7 @@
#include <thread>
#include <android-base/file.h>
+#include <android-base/macros.h>
#include <android-base/scopeguard.h>
#include "gtest_globals.h"
@@ -966,17 +967,7 @@
#endif
}
-#if defined (__aarch64__)
-#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib64/arm64/"
-#elif defined (__arm__)
-#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib/arm/"
-#elif defined (__i386__)
-#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib/x86/"
-#elif defined (__x86_64__)
-#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib64/x86_64/"
-#else
-#error "Unknown architecture"
-#endif
+#define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib64/" ABI_STRING "/"
#define PATH_TO_LIBC PATH_TO_SYSTEM_LIB "libc.so"
#define PATH_TO_BOOTSTRAP_LIBC PATH_TO_SYSTEM_LIB "bootstrap/libc.so"
#define ALTERNATE_PATH_TO_LIBC ALTERNATE_PATH_TO_SYSTEM_LIB "libc.so"
diff --git a/tests/fenv_test.cpp b/tests/fenv_test.cpp
index c5b5eca..9cf9d98 100644
--- a/tests/fenv_test.cpp
+++ b/tests/fenv_test.cpp
@@ -117,6 +117,21 @@
ASSERT_EQ(FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT));
}
+TEST(fenv, fegetenv_fesetenv_rounding_mode) {
+ // Test that fegetenv()/fesetenv() includes the rounding mode.
+ fesetround(FE_DOWNWARD);
+ ASSERT_EQ(FE_DOWNWARD, fegetround());
+
+ fenv_t env;
+ fegetenv(&env);
+
+ fesetround(FE_UPWARD);
+ ASSERT_EQ(FE_UPWARD, fegetround());
+
+ fesetenv(&env);
+ ASSERT_EQ(FE_DOWNWARD, fegetround());
+}
+
TEST(fenv, feholdexcept_feupdateenv) {
// Set FE_OVERFLOW only.
feclearexcept(FE_ALL_EXCEPT);
@@ -187,9 +202,10 @@
TEST(fenv, feenableexcept_fegetexcept) {
#if !defined(ANDROID_HOST_MUSL)
-#if defined(__aarch64__) || defined(__arm__)
- // ARM doesn't support this. They used to if you go back far enough, but it was removed in
- // the Cortex-A8 between r3p1 and r3p2.
+#if defined(__aarch64__) || defined(__arm__) || defined(__riscv)
+ // ARM and RISC-V don't support hardware trapping of floating point
+ // exceptions. ARM used to if you go back far enough, but it was
+ // removed in the Cortex-A8 between r3p1 and r3p2. RISC-V never has.
ASSERT_EQ(-1, feenableexcept(FE_INVALID));
ASSERT_EQ(0, fegetexcept());
ASSERT_EQ(-1, feenableexcept(FE_DIVBYZERO));
@@ -200,8 +216,10 @@
ASSERT_EQ(0, fegetexcept());
ASSERT_EQ(-1, feenableexcept(FE_INEXACT));
ASSERT_EQ(0, fegetexcept());
+#if defined(_FE_DENORMAL) // riscv64 doesn't support this.
ASSERT_EQ(-1, feenableexcept(FE_DENORMAL));
ASSERT_EQ(0, fegetexcept());
+#endif
#else
// We can't recover from SIGFPE, so sacrifice a child...
pid_t pid = fork();
diff --git a/tests/gwp_asan_test.cpp b/tests/gwp_asan_test.cpp
index b2c7780..5f5e3dd 100644
--- a/tests/gwp_asan_test.cpp
+++ b/tests/gwp_asan_test.cpp
@@ -28,26 +28,28 @@
#include <gtest/gtest.h>
#include <stdio.h>
+#include <sys/file.h>
#include <string>
#if defined(__BIONIC__)
+#include "android-base/file.h"
#include "gwp_asan/options.h"
#include "platform/bionic/malloc.h"
+#include "sys/system_properties.h"
#include "utils.h"
-void RunGwpAsanTest(const char* test_name) {
- ExecTestHelper eh;
- eh.SetEnv({"GWP_ASAN_SAMPLE_RATE=1", "GWP_ASAN_PROCESS_SAMPLING=1", "GWP_ASAN_MAX_ALLOCS=40000",
- nullptr});
- std::string filter_arg = "--gtest_filter=";
- filter_arg += test_name;
- std::string exec(testing::internal::GetArgvs()[0]);
- eh.SetArgs({exec.c_str(), "--gtest_also_run_disabled_tests", filter_arg.c_str(), nullptr});
- eh.Run([&]() { execve(exec.c_str(), eh.GetArgs(), eh.GetEnv()); },
- /* expected_exit_status */ 0,
- // |expected_output_regex|, ensure at least one test ran:
- R"(\[ PASSED \] [1-9]+0? test)");
+// basename is a mess, use gnu basename explicitly to avoid the need for string
+// mutation.
+extern "C" const char* __gnu_basename(const char* path);
+
+// GWP-ASan tests can run much slower, especially when combined with HWASan.
+// Triple the deadline to avoid flakes (b/238585984).
+extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) {
+ static const char* initial_args[] = {"--deadline_threshold_ms=270000"};
+ *args = initial_args;
+ *num_args = 1;
+ return true;
}
// This file implements "torture testing" under GWP-ASan, where we sample every
@@ -58,4 +60,191 @@
RunGwpAsanTest("malloc.*:-malloc.mallinfo*");
}
+class SyspropRestorer {
+ private:
+ std::vector<std::pair<std::string, std::string>> props_to_restore_;
+ // System properties are global for a device, so the tests that mutate the
+ // GWP-ASan system properties must be run mutually exclusive. Because
+ // bionic-unit-tests is run in an isolated gtest fashion (each test is run in
+ // its own process), we have to use flocks to synchronise between tests.
+ int flock_fd_;
+
+ public:
+ SyspropRestorer() {
+ std::string path = testing::internal::GetArgvs()[0];
+ flock_fd_ = open(path.c_str(), O_RDONLY);
+ EXPECT_NE(flock_fd_, -1) << "failed to open self for a flock";
+ EXPECT_NE(flock(flock_fd_, LOCK_EX), -1) << "failed to flock myself";
+
+ const char* basename = __gnu_basename(path.c_str());
+ std::vector<std::string> props = {
+ std::string("libc.debug.gwp_asan.sample_rate.") + basename,
+ std::string("libc.debug.gwp_asan.process_sampling.") + basename,
+ std::string("libc.debug.gwp_asan.max_allocs.") + basename,
+ "libc.debug.gwp_asan.sample_rate.system_default",
+ "libc.debug.gwp_asan.sample_rate.app_default",
+ "libc.debug.gwp_asan.process_sampling.system_default",
+ "libc.debug.gwp_asan.process_sampling.app_default",
+ "libc.debug.gwp_asan.max_allocs.system_default",
+ "libc.debug.gwp_asan.max_allocs.app_default",
+ };
+
+ size_t base_props_size = props.size();
+ for (size_t i = 0; i < base_props_size; ++i) {
+ props.push_back("persist." + props[i]);
+ }
+
+ std::string reset_log;
+
+ for (const std::string& prop : props) {
+ std::string value = GetSysprop(prop);
+ props_to_restore_.emplace_back(prop, value);
+ if (!value.empty()) {
+ __system_property_set(prop.c_str(), "");
+ }
+ }
+ }
+
+ ~SyspropRestorer() {
+ for (const auto& kv : props_to_restore_) {
+ if (kv.second != GetSysprop(kv.first)) {
+ __system_property_set(kv.first.c_str(), kv.second.c_str());
+ }
+ }
+ close(flock_fd_);
+ }
+
+ static std::string GetSysprop(const std::string& name) {
+ std::string value;
+ const prop_info* pi = __system_property_find(name.c_str());
+ if (pi == nullptr) return value;
+ __system_property_read_callback(
+ pi,
+ [](void* cookie, const char* /* name */, const char* value, uint32_t /* serial */) {
+ std::string* v = static_cast<std::string*>(cookie);
+ *v = value;
+ },
+ &value);
+ return value;
+ }
+};
+
+TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_enabled) {
+ std::string maps;
+ EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
+ EXPECT_TRUE(maps.find("GWP-ASan") != std::string::npos) << maps;
+
+ volatile int* x = new int;
+ delete x;
+ EXPECT_DEATH({ *x = 7; }, "");
+}
+
+TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_disabled) {
+ std::string maps;
+ EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
+ EXPECT_TRUE(maps.find("GWP-ASan") == std::string::npos);
+}
+
+TEST(gwp_asan_integration, sysprops_program_specific) {
+ SyspropRestorer restorer;
+
+ std::string path = testing::internal::GetArgvs()[0];
+ const char* basename = __gnu_basename(path.c_str());
+ __system_property_set((std::string("libc.debug.gwp_asan.sample_rate.") + basename).c_str(), "1");
+ __system_property_set((std::string("libc.debug.gwp_asan.process_sampling.") + basename).c_str(),
+ "1");
+ __system_property_set((std::string("libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
+ "40000");
+
+ RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+}
+
+TEST(gwp_asan_integration, sysprops_persist_program_specific) {
+ SyspropRestorer restorer;
+
+ std::string path = testing::internal::GetArgvs()[0];
+ const char* basename = __gnu_basename(path.c_str());
+ __system_property_set(
+ (std::string("persist.libc.debug.gwp_asan.sample_rate.") + basename).c_str(), "1");
+ __system_property_set(
+ (std::string("persist.libc.debug.gwp_asan.process_sampling.") + basename).c_str(), "1");
+ __system_property_set((std::string("persist.libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
+ "40000");
+
+ RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+}
+
+TEST(gwp_asan_integration, sysprops_system) {
+ SyspropRestorer restorer;
+
+ __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
+ __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "1");
+ __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "40000");
+
+ RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+}
+
+TEST(gwp_asan_integration, sysprops_persist_system) {
+ SyspropRestorer restorer;
+
+ __system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "1");
+ __system_property_set("persist.libc.debug.gwp_asan.process_sampling.system_default", "1");
+ __system_property_set("persist.libc.debug.gwp_asan.max_allocs.system_default", "40000");
+
+ RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+}
+
+TEST(gwp_asan_integration, sysprops_non_persist_overrides_persist) {
+ SyspropRestorer restorer;
+
+ __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
+ __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "1");
+ __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "40000");
+
+ __system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "0");
+ __system_property_set("persist.libc.debug.gwp_asan.process_sampling.system_default", "0");
+ __system_property_set("persist.libc.debug.gwp_asan.max_allocs.system_default", "0");
+
+ RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+}
+
+TEST(gwp_asan_integration, sysprops_program_specific_overrides_default) {
+ SyspropRestorer restorer;
+
+ std::string path = testing::internal::GetArgvs()[0];
+ const char* basename = __gnu_basename(path.c_str());
+ __system_property_set(
+ (std::string("persist.libc.debug.gwp_asan.sample_rate.") + basename).c_str(), "1");
+ __system_property_set(
+ (std::string("persist.libc.debug.gwp_asan.process_sampling.") + basename).c_str(), "1");
+ __system_property_set((std::string("persist.libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
+ "40000");
+
+ __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
+ __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
+ __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
+
+ RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+}
+
+TEST(gwp_asan_integration, sysprops_can_disable) {
+ SyspropRestorer restorer;
+
+ __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
+ __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
+ __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
+
+ RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_disabled");
+}
+
+TEST(gwp_asan_integration, env_overrides_sysprop) {
+ SyspropRestorer restorer;
+
+ __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
+ __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
+ __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
+
+ RunGwpAsanTest("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+}
+
#endif // defined(__BIONIC__)
diff --git a/tests/headers/posix/sys_stat_h.c b/tests/headers/posix/sys_stat_h.c
index b22e34f..a299426 100644
--- a/tests/headers/posix/sys_stat_h.c
+++ b/tests/headers/posix/sys_stat_h.c
@@ -69,7 +69,7 @@
STRUCT_MEMBER(struct stat, struct timespec, st_mtim);
STRUCT_MEMBER(struct stat, struct timespec, st_ctim);
#if defined(__BIONIC__)
-#if defined(__aarch64__)
+#if defined(__aarch64__) || defined(__riscv)
STRUCT_MEMBER(struct stat, int, st_blksize);
#elif defined(__x86_64__)
STRUCT_MEMBER(struct stat, long, st_blksize);
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 0046ef6..0c9a2e0 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -41,6 +41,9 @@
enabled: false,
},
},
+ strip: {
+ none: true,
+ },
}
// -----------------------------------------------------------------------------
@@ -1532,12 +1535,6 @@
host_supported: false,
defaults: ["bionic_testlib_defaults"],
srcs: ["relocations.cpp"],
-
- // Hack to ensure we're using llvm-objcopy because our binutils prebuilt
- // only supports the old numbers (http://b/141010852).
- strip: {
- keep_symbols: true,
- },
}
// This is the same encoding as SHT_RELR, but using OS-specific constants.
@@ -1652,6 +1649,35 @@
},
}
+cc_test {
+ name: "stack_tagging_helper",
+ defaults: ["bionic_testlib_defaults", "bionic_targets_only"],
+ srcs: ["stack_tagging_helper.cpp"],
+ sanitize: {
+ memtag_heap: true,
+ memtag_stack: true,
+ diag: {
+ memtag_heap: true,
+ },
+ },
+ header_libs: ["bionic_libc_platform_headers"],
+}
+
+cc_test {
+ name: "stack_tagging_static_helper",
+ defaults: ["bionic_testlib_defaults", "bionic_targets_only"],
+ srcs: ["stack_tagging_helper.cpp"],
+ static_executable: true,
+ sanitize: {
+ memtag_heap: true,
+ memtag_stack: true,
+ diag: {
+ memtag_heap: true,
+ },
+ },
+ header_libs: ["bionic_libc_platform_headers"],
+}
+
cc_genrule {
name: "libdlext_test_zip_zipaligned",
out: ["bionic-loader-test-libs/libdlext_test_zip/libdlext_test_zip_zipaligned.zip"],
diff --git a/tests/libs/heap_tagging_helper.cpp b/tests/libs/heap_tagging_helper.cpp
index 16a8c8b..ed5601a 100644
--- a/tests/libs/heap_tagging_helper.cpp
+++ b/tests/libs/heap_tagging_helper.cpp
@@ -49,6 +49,10 @@
sa.sa_sigaction = action;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &sa, nullptr);
+ // suppress HWASan crash in logcat / tombstone.
+ struct sigaction dfl_sa = {};
+ dfl_sa.sa_handler = SIG_DFL;
+ sigaction(SIGABRT, &dfl_sa, nullptr);
std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
volatile int oob = p[-1];
diff --git a/tests/libs/stack_tagging_helper.cpp b/tests/libs/stack_tagging_helper.cpp
new file mode 100644
index 0000000..a239dc1
--- /dev/null
+++ b/tests/libs/stack_tagging_helper.cpp
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2022 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 <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <thread>
+
+#include <bionic/malloc.h>
+
+#include "libs_utils.h"
+
+#if defined(__aarch64__)
+
+template <typename T>
+static inline void mte_set_tag(T* p) {
+ __asm__ __volatile__(
+ ".arch_extension memtag\n"
+ "stg %[Ptr], [%[Ptr]]\n"
+ :
+ : [Ptr] "r"(p)
+ : "memory");
+}
+
+template <typename T>
+static inline T* mte_get_tag(T* p) {
+ __asm__ __volatile__(
+ ".arch_extension memtag\n"
+ "ldg %[Ptr], [%[Ptr]]\n"
+ : [Ptr] "+r"(p)
+ :
+ : "memory");
+ return p;
+}
+
+template <typename T>
+static inline T* mte_increment_tag(T* p) {
+ T* res;
+ __asm__ __volatile__(
+ ".arch_extension memtag\n"
+ "addg %[Res], %[Ptr], #0, #1\n"
+ : [Res] "=r"(res)
+ : [Ptr] "r"(p)
+ : "memory");
+ return res;
+}
+
+constexpr size_t kStackAllocationSize = 128 * 1024;
+
+// Prevent optimizations.
+volatile void* sink;
+
+enum struct ChildAction { Exit, Execve, Execl };
+
+// Either execve or _exit, transferring control back to parent.
+__attribute__((no_sanitize("memtag"), optnone, noinline)) void vfork_child2(ChildAction action,
+ void* fp_parent) {
+ // Make sure that the buffer in the caller has not been optimized out.
+ void* fp = __builtin_frame_address(0);
+ CHECK(reinterpret_cast<uintptr_t>(fp_parent) - reinterpret_cast<uintptr_t>(fp) >=
+ kStackAllocationSize);
+ if (action == ChildAction::Execve) {
+ const char* argv[] = {"/system/bin/true", nullptr};
+ const char* envp[] = {nullptr};
+ execve("/system/bin/true", const_cast<char**>(argv), const_cast<char**>(envp));
+ fprintf(stderr, "execve failed: %m\n");
+ _exit(1);
+ } else if (action == ChildAction::Execl) {
+ execl("/system/bin/true", "/system/bin/true", "unusedA", "unusedB", nullptr);
+ fprintf(stderr, "execl failed: %m\n");
+ _exit(1);
+ } else if (action == ChildAction::Exit) {
+ _exit(0);
+ }
+ CHECK(0);
+}
+
+// Place a tagged buffer on the stack. Do not tag the top half so that the parent does not crash too
+// early even if things go wrong.
+__attribute__((no_sanitize("memtag"), optnone, noinline)) void vfork_child(ChildAction action) {
+ alignas(16) char buf[kStackAllocationSize] __attribute__((uninitialized));
+ sink = &buf;
+
+ for (char* p = buf; p < buf + sizeof(buf) / 2; p += 16) {
+ char* q = mte_increment_tag(p);
+ mte_set_tag(q);
+ CHECK(mte_get_tag(p) == q);
+ }
+ vfork_child2(action, __builtin_frame_address(0));
+}
+
+// Parent. Check that the stack has correct allocation tags.
+__attribute__((no_sanitize("memtag"), optnone, noinline)) void vfork_parent(pid_t pid) {
+ alignas(16) char buf[kStackAllocationSize] __attribute__((uninitialized));
+ fprintf(stderr, "vfork_parent %p\n", &buf);
+ bool success = true;
+ for (char* p = buf; p < buf + sizeof(buf); p += 16) {
+ char* q = mte_get_tag(p);
+ if (p != q) {
+ fprintf(stderr, "tag mismatch at offset %zx: %p != %p\n", p - buf, p, q);
+ success = false;
+ break;
+ }
+ }
+
+ int wstatus;
+ do {
+ int res = waitpid(pid, &wstatus, 0);
+ CHECK(res == pid);
+ } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
+
+ CHECK(WIFEXITED(wstatus));
+ CHECK(WEXITSTATUS(wstatus) == 0);
+
+ if (!success) exit(1);
+}
+
+void test_vfork(ChildAction action) {
+ pid_t pid = vfork();
+ if (pid == 0) {
+ vfork_child(action);
+ } else {
+ vfork_parent(pid);
+ }
+}
+
+__attribute__((no_sanitize("memtag"), optnone, noinline)) static void settag_and_longjmp(
+ jmp_buf cont) {
+ alignas(16) char buf[kStackAllocationSize] __attribute__((uninitialized));
+ sink = &buf;
+
+ for (char* p = buf; p < buf + sizeof(buf) / 2; p += 16) {
+ char* q = mte_increment_tag(p);
+ mte_set_tag(q);
+ if (mte_get_tag(p) != q) {
+ fprintf(stderr, "failed to set allocation tags on stack: %p != %p\n", mte_get_tag(p), q);
+ exit(1);
+ }
+ }
+ longjmp(cont, 42);
+}
+
+// Check that the stack has correct allocation tags.
+__attribute__((no_sanitize("memtag"), optnone, noinline)) static void check_stack_tags() {
+ alignas(16) char buf[kStackAllocationSize] __attribute__((uninitialized));
+ for (char* p = buf; p < buf + sizeof(buf); p += 16) {
+ void* q = mte_get_tag(p);
+ if (p != q) {
+ fprintf(stderr, "stack tags mismatch: expected %p, got %p", p, q);
+ exit(1);
+ }
+ }
+}
+
+void check_longjmp_restores_tags() {
+ int value;
+ jmp_buf jb;
+ if ((value = setjmp(jb)) == 0) {
+ settag_and_longjmp(jb);
+ exit(2); // Unreachable.
+ } else {
+ CHECK(value == 42);
+ check_stack_tags();
+ }
+}
+
+class SigAltStackScoped {
+ stack_t old_ss;
+ void* altstack_start;
+ size_t altstack_size;
+
+ public:
+ SigAltStackScoped(size_t sz) : altstack_size(sz) {
+ altstack_start = mmap(nullptr, altstack_size, PROT_READ | PROT_WRITE | PROT_MTE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ if (altstack_start == MAP_FAILED) {
+ fprintf(stderr, "sigaltstack mmap failed: %m\n");
+ exit(1);
+ }
+ stack_t ss = {};
+ ss.ss_sp = altstack_start;
+ ss.ss_size = altstack_size;
+ int res = sigaltstack(&ss, &old_ss);
+ CHECK(res == 0);
+ }
+
+ ~SigAltStackScoped() {
+ int res = sigaltstack(&old_ss, nullptr);
+ CHECK(res == 0);
+ munmap(altstack_start, altstack_size);
+ }
+};
+
+class SigActionScoped {
+ int signo;
+ struct sigaction oldsa;
+
+ public:
+ using handler_t = void (*)(int, siginfo_t* siginfo, void*);
+
+ SigActionScoped(int signo, handler_t handler) : signo(signo) {
+ struct sigaction sa = {};
+ sa.sa_sigaction = handler;
+ sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
+ int res = sigaction(signo, &sa, &oldsa);
+ CHECK(res == 0);
+ }
+
+ ~SigActionScoped() {
+ int res = sigaction(signo, &oldsa, nullptr);
+ CHECK(res == 0);
+ }
+};
+
+void test_longjmp() {
+ check_longjmp_restores_tags();
+
+ std::thread t([]() { check_longjmp_restores_tags(); });
+ t.join();
+}
+
+void test_longjmp_sigaltstack() {
+ constexpr size_t kAltStackSize = kStackAllocationSize + PAGE_SIZE * 16;
+ SigAltStackScoped sigAltStackScoped(kAltStackSize);
+ SigActionScoped sigActionScoped(
+ SIGUSR1, [](int, siginfo_t*, void*) { check_longjmp_restores_tags(); });
+ raise(SIGUSR1);
+
+ // same for a secondary thread
+ std::thread t([]() {
+ SigAltStackScoped sigAltStackScoped(kAltStackSize);
+ raise(SIGUSR1);
+ });
+ t.join();
+}
+
+void test_android_mallopt() {
+ bool memtag_stack;
+ CHECK(android_mallopt(M_MEMTAG_STACK_IS_ON, &memtag_stack, sizeof(memtag_stack)));
+ CHECK(memtag_stack);
+}
+
+int main(int argc, char** argv) {
+ if (argc < 2) {
+ printf("nothing to do\n");
+ return 1;
+ }
+
+ if (strcmp(argv[1], "vfork_execve") == 0) {
+ test_vfork(ChildAction::Execve);
+ return 0;
+ }
+
+ if (strcmp(argv[1], "vfork_execl") == 0) {
+ test_vfork(ChildAction::Execl);
+ return 0;
+ }
+
+ if (strcmp(argv[1], "vfork_exit") == 0) {
+ test_vfork(ChildAction::Exit);
+ return 0;
+ }
+
+ if (strcmp(argv[1], "longjmp") == 0) {
+ test_longjmp();
+ return 0;
+ }
+
+ if (strcmp(argv[1], "longjmp_sigaltstack") == 0) {
+ test_longjmp_sigaltstack();
+ return 0;
+ }
+
+ if (strcmp(argv[1], "android_mallopt") == 0) {
+ test_android_mallopt();
+ return 0;
+ }
+
+ printf("unrecognized command: %s\n", argv[1]);
+ return 1;
+}
+#else
+int main(int, char**) {
+ printf("aarch64 only\n");
+ return 1;
+}
+#endif // defined(__aarch64__)
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 69f8506..3cc5bbd 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -1383,6 +1383,15 @@
#endif
}
+TEST(android_mallopt, memtag_stack_is_on) {
+#if defined(__BIONIC__)
+ bool memtag_stack;
+ EXPECT_TRUE(android_mallopt(M_MEMTAG_STACK_IS_ON, &memtag_stack, sizeof(memtag_stack)));
+#else
+ GTEST_SKIP() << "bionic extension";
+#endif
+}
+
void TestHeapZeroing(int num_iterations, int (*get_alloc_size)(int iteration)) {
std::vector<void*> allocs;
constexpr int kMaxBytesToCheckZero = 64;
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 76b5078..60872f3 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -1053,22 +1053,22 @@
auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
fesetround(FE_UPWARD); // lrint/lrintf/lrintl obey the rounding mode.
- ASSERT_EQ(1235, lrint(1234.01));
- ASSERT_EQ(1235, lrintf(1234.01f));
- ASSERT_EQ(1235, lrintl(1234.01L));
+ EXPECT_EQ(1235, lrint(1234.01));
+ EXPECT_EQ(1235, lrintf(1234.01f));
+ EXPECT_EQ(1235, lrintl(1234.01L));
fesetround(FE_TOWARDZERO); // lrint/lrintf/lrintl obey the rounding mode.
- ASSERT_EQ(1234, lrint(1234.01));
- ASSERT_EQ(1234, lrintf(1234.01f));
- ASSERT_EQ(1234, lrintl(1234.01L));
+ EXPECT_EQ(1234, lrint(1234.01));
+ EXPECT_EQ(1234, lrintf(1234.01f));
+ EXPECT_EQ(1234, lrintl(1234.01L));
fesetround(FE_UPWARD); // llrint/llrintf/llrintl obey the rounding mode.
- ASSERT_EQ(1235L, llrint(1234.01));
- ASSERT_EQ(1235L, llrintf(1234.01f));
- ASSERT_EQ(1235L, llrintl(1234.01L));
+ EXPECT_EQ(1235L, llrint(1234.01));
+ EXPECT_EQ(1235L, llrintf(1234.01f));
+ EXPECT_EQ(1235L, llrintl(1234.01L));
fesetround(FE_TOWARDZERO); // llrint/llrintf/llrintl obey the rounding mode.
- ASSERT_EQ(1234L, llrint(1234.01));
- ASSERT_EQ(1234L, llrintf(1234.01f));
- ASSERT_EQ(1234L, llrintl(1234.01L));
+ EXPECT_EQ(1234L, llrint(1234.01));
+ EXPECT_EQ(1234L, llrintf(1234.01f));
+ EXPECT_EQ(1234L, llrintl(1234.01L));
}
TEST(MATH_TEST, rint) {
diff --git a/tests/memtag_stack_test.cpp b/tests/memtag_stack_test.cpp
new file mode 100644
index 0000000..84ee8d1
--- /dev/null
+++ b/tests/memtag_stack_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 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 <tuple>
+
+#include <gtest/gtest.h>
+
+#if defined(__BIONIC__)
+#include "gtest_globals.h"
+#include "platform/bionic/mte.h"
+#include "utils.h"
+#endif
+
+class MemtagStackTest : public testing::TestWithParam<std::tuple<const char*, bool>> {};
+
+TEST_P(MemtagStackTest, test) {
+#if defined(__BIONIC__) && defined(__aarch64__)
+ if (!mte_supported()) {
+ GTEST_SKIP() << "MTE unsupported";
+ }
+ bool is_static = std::get<1>(GetParam());
+ std::string helper =
+ GetTestlibRoot() + (is_static ? "/stack_tagging_static_helper" : "/stack_tagging_helper");
+ const char* arg = std::get<0>(GetParam());
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({helper.c_str(), arg, nullptr});
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "");
+#else
+ GTEST_SKIP() << "bionic/arm64 only";
+#endif
+}
+
+INSTANTIATE_TEST_SUITE_P(, MemtagStackTest,
+ testing::Combine(testing::Values("vfork_execve", "vfork_execl",
+ "vfork_exit", "longjmp",
+ "longjmp_sigaltstack", "android_mallopt"),
+ testing::Bool()),
+ [](const ::testing::TestParamInfo<MemtagStackTest::ParamType>& info) {
+ std::string s = std::get<0>(info.param);
+ if (std::get<1>(info.param)) s += "_static";
+ return s;
+ });
diff --git a/tests/mte_test.cpp b/tests/mte_test.cpp
index ade9532..5eb804f 100644
--- a/tests/mte_test.cpp
+++ b/tests/mte_test.cpp
@@ -32,6 +32,7 @@
reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(p.get()) + (1ULL << 56));
{
ScopedDisableMTE x;
+ // Test that nested ScopedDisableMTE does not reset MTE state.
{ ScopedDisableMTE y; }
#if defined(__aarch64__)
volatile int load ATTRIBUTE_UNUSED = *mistagged_p;
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index 472aa20..2f891ec 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -81,8 +81,10 @@
sigset64_t ss;
sigemptyset64(&ss);
sigaddset64(&ss, SIGUSR1 + offset);
+#if defined(__BIONIC__)
// TIMER_SIGNAL.
sigaddset64(&ss, __SIGRTMIN);
+#endif
sigaddset64(&ss, SIGRTMIN + offset);
return ss;
}
@@ -224,13 +226,15 @@
}
#if defined(__arm__)
-#define __JB_SIGFLAG 0
+#define JB_SIGFLAG_OFFSET 0
#elif defined(__aarch64__)
-#define __JB_SIGFLAG 0
+#define JB_SIGFLAG_OFFSET 0
#elif defined(__i386__)
-#define __JB_SIGFLAG 8
+#define JB_SIGFLAG_OFFSET 8
+#elif defined(__riscv)
+#define JB_SIGFLAG_OFFSET 0
#elif defined(__x86_64)
-#define __JB_SIGFLAG 8
+#define JB_SIGFLAG_OFFSET 8
#endif
TEST_F(setjmp_DeathTest, setjmp_cookie) {
@@ -238,7 +242,7 @@
int value = setjmp(jb);
ASSERT_EQ(0, value);
- long* sigflag = reinterpret_cast<long*>(jb) + __JB_SIGFLAG;
+ long* sigflag = reinterpret_cast<long*>(jb) + JB_SIGFLAG_OFFSET;
// Make sure there's actually a cookie.
EXPECT_NE(0, *sigflag & ~1);
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 5bda8b3..7f7f3db 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -34,6 +34,13 @@
using namespace std::chrono_literals;
+#if defined(ANDROID_HOST_MUSL)
+// Musl doesn't export __SIGRTMIN and __SIGRTMAX, #define
+// them here.
+#define __SIGRTMIN 32
+#define __SIGRTMAX 64
+#endif
+
static int SIGNAL_MIN() {
return 1; // Signals start at 1 (SIGHUP), not 0.
}
diff --git a/tests/stdio_ext_test.cpp b/tests/stdio_ext_test.cpp
index fce600a..dce1a66 100644
--- a/tests/stdio_ext_test.cpp
+++ b/tests/stdio_ext_test.cpp
@@ -78,6 +78,24 @@
fclose(fp);
}
+TEST(stdio_ext, __freadahead) {
+#if defined(__GLIBC__)
+ GTEST_SKIP() << "glibc doesn't have __freadahead";
+#else
+ FILE* fp = tmpfile();
+ ASSERT_NE(EOF, fputs("hello", fp));
+ rewind(fp);
+
+ ASSERT_EQ('h', fgetc(fp));
+ ASSERT_EQ(4u, __freadahead(fp));
+
+ ASSERT_EQ('H', ungetc('H', fp));
+ ASSERT_EQ(5u, __freadahead(fp));
+
+ fclose(fp);
+#endif
+}
+
TEST(stdio_ext, __fpurge) {
FILE* fp = tmpfile();
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 87031f6..acc7ccd 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -25,6 +25,7 @@
#include <sys/cdefs.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/sysinfo.h>
#include <sys/types.h>
#include <unistd.h>
#include <wchar.h>
@@ -364,13 +365,13 @@
TEST_F(STDIO_DEATHTEST, snprintf_n) {
#if defined(__BIONIC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat"
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
// http://b/14492135 and http://b/31832608.
char buf[32];
int i = 1234;
EXPECT_DEATH(snprintf(buf, sizeof(buf), "a %n b", &i), "%n not allowed on Android");
-#pragma GCC diagnostic pop
+#pragma clang diagnostic pop
#else
GTEST_SKIP() << "glibc does allow %n";
#endif
@@ -489,22 +490,22 @@
// NaN.
- snprintf_fn(buf, sizeof(buf), fmt, nanf(""));
+ snprintf_fn(buf, sizeof(buf), fmt, nan(""));
EXPECT_STREQ(nan_, buf) << fmt;
EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
EXPECT_TRUE(isnan(f));
- snprintf_fn(buf, sizeof(buf), fmt, -nanf(""));
+ snprintf_fn(buf, sizeof(buf), fmt, -nan(""));
EXPECT_STREQ(minus_nan, buf) << fmt;
EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
EXPECT_TRUE(isnan(f));
- snprintf_fn(buf, sizeof(buf), fmt_plus, nanf(""));
+ snprintf_fn(buf, sizeof(buf), fmt_plus, nan(""));
EXPECT_STREQ(plus_nan, buf) << fmt_plus;
EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
EXPECT_TRUE(isnan(f));
- snprintf_fn(buf, sizeof(buf), fmt_plus, -nanf(""));
+ snprintf_fn(buf, sizeof(buf), fmt_plus, -nan(""));
EXPECT_STREQ(minus_nan, buf) << fmt_plus;
EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
EXPECT_TRUE(isnan(f));
@@ -2938,3 +2939,245 @@
fclose(fp);
}
+
+#if defined(__LP64__)
+static int64_t GetTotalRamGiB() {
+ struct sysinfo si;
+ sysinfo(&si);
+ return (static_cast<int64_t>(si.totalram) * si.mem_unit) / 1024 / 1024 / 1024;
+}
+#endif
+
+TEST(STDIO_TEST, fread_int_overflow) {
+#if defined(__LP64__)
+ if (GetTotalRamGiB() <= 4) GTEST_SKIP() << "not enough memory";
+
+ const size_t too_big_for_an_int = 0x80000000ULL;
+ std::vector<char> buf(too_big_for_an_int);
+ std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/dev/zero", "re"), fclose};
+ ASSERT_EQ(too_big_for_an_int, fread(&buf[0], 1, too_big_for_an_int, fp.get()));
+#else
+ GTEST_SKIP() << "32-bit can't allocate 2GiB";
+#endif
+}
+
+TEST(STDIO_TEST, fwrite_int_overflow) {
+#if defined(__LP64__)
+ if (GetTotalRamGiB() <= 4) GTEST_SKIP() << "not enough memory";
+
+ const size_t too_big_for_an_int = 0x80000000ULL;
+ std::vector<char> buf(too_big_for_an_int);
+ std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/dev/null", "we"), fclose};
+ ASSERT_EQ(too_big_for_an_int, fwrite(&buf[0], 1, too_big_for_an_int, fp.get()));
+#else
+ GTEST_SKIP() << "32-bit can't allocate 2GiB";
+#endif
+}
+
+TEST(STDIO_TEST, snprintf_b) {
+ // Our clang doesn't know about %b/%B yet.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ char buf[BUFSIZ];
+ EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%b>", 5));
+ EXPECT_STREQ("<101>", buf);
+ EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%08b>", 5));
+ EXPECT_STREQ("<00000101>", buf);
+ EXPECT_EQ(34, snprintf(buf, sizeof(buf), "<%b>", 0xaaaaaaaa));
+ EXPECT_STREQ("<10101010101010101010101010101010>", buf);
+ EXPECT_EQ(36, snprintf(buf, sizeof(buf), "<%#b>", 0xaaaaaaaa));
+ EXPECT_STREQ("<0b10101010101010101010101010101010>", buf);
+ EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#b>", 0));
+ EXPECT_STREQ("<0>", buf);
+#pragma clang diagnostic pop
+}
+
+TEST(STDIO_TEST, snprintf_B) {
+ // Our clang doesn't know about %b/%B yet.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ char buf[BUFSIZ];
+ EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%B>", 5));
+ EXPECT_STREQ("<101>", buf);
+ EXPECT_EQ(10, snprintf(buf, sizeof(buf), "<%08B>", 5));
+ EXPECT_STREQ("<00000101>", buf);
+ EXPECT_EQ(34, snprintf(buf, sizeof(buf), "<%B>", 0xaaaaaaaa));
+ EXPECT_STREQ("<10101010101010101010101010101010>", buf);
+ EXPECT_EQ(36, snprintf(buf, sizeof(buf), "<%#B>", 0xaaaaaaaa));
+ EXPECT_STREQ("<0B10101010101010101010101010101010>", buf);
+ EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#B>", 0));
+ EXPECT_STREQ("<0>", buf);
+#pragma clang diagnostic pop
+}
+
+TEST(STDIO_TEST, swprintf_b) {
+ // Our clang doesn't know about %b/%B yet.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ wchar_t buf[BUFSIZ];
+ EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%b>", 5));
+ EXPECT_EQ(std::wstring(L"<101>"), buf);
+ EXPECT_EQ(10, swprintf(buf, sizeof(buf), L"<%08b>", 5));
+ EXPECT_EQ(std::wstring(L"<00000101>"), buf);
+ EXPECT_EQ(34, swprintf(buf, sizeof(buf), L"<%b>", 0xaaaaaaaa));
+ EXPECT_EQ(std::wstring(L"<10101010101010101010101010101010>"), buf);
+ EXPECT_EQ(36, swprintf(buf, sizeof(buf), L"<%#b>", 0xaaaaaaaa));
+ EXPECT_EQ(std::wstring(L"<0b10101010101010101010101010101010>"), buf);
+ EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#b>", 0));
+ EXPECT_EQ(std::wstring(L"<0>"), buf);
+#pragma clang diagnostic pop
+}
+
+TEST(STDIO_TEST, swprintf_B) {
+ // Our clang doesn't know about %b/%B yet.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ wchar_t buf[BUFSIZ];
+ EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%B>", 5));
+ EXPECT_EQ(std::wstring(L"<101>"), buf);
+ EXPECT_EQ(10, swprintf(buf, sizeof(buf), L"<%08B>", 5));
+ EXPECT_EQ(std::wstring(L"<00000101>"), buf);
+ EXPECT_EQ(34, swprintf(buf, sizeof(buf), L"<%B>", 0xaaaaaaaa));
+ EXPECT_EQ(std::wstring(L"<10101010101010101010101010101010>"), buf);
+ EXPECT_EQ(36, swprintf(buf, sizeof(buf), L"<%#B>", 0xaaaaaaaa));
+ EXPECT_EQ(std::wstring(L"<0B10101010101010101010101010101010>"), buf);
+ EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#B>", 0));
+ EXPECT_EQ(std::wstring(L"<0>"), buf);
+#pragma clang diagnostic pop
+}
+
+TEST(STDIO_TEST, scanf_i_decimal) {
+ int i;
+ EXPECT_EQ(1, sscanf("<123789>", "<%i>", &i));
+ EXPECT_EQ(123789, i);
+
+ long long int lli;
+ char ch;
+ EXPECT_EQ(2, sscanf("1234567890abcdefg", "%lli%c", &lli, &ch));
+ EXPECT_EQ(1234567890, lli);
+ EXPECT_EQ('a', ch);
+}
+
+TEST(STDIO_TEST, scanf_i_hex) {
+ int i;
+ EXPECT_EQ(1, sscanf("<0x123abf>", "<%i>", &i));
+ EXPECT_EQ(0x123abf, i);
+
+ long long int lli;
+ char ch;
+ EXPECT_EQ(2, sscanf("0x1234567890abcdefg", "%lli%c", &lli, &ch));
+ EXPECT_EQ(0x1234567890abcdefLL, lli);
+ EXPECT_EQ('g', ch);
+}
+
+TEST(STDIO_TEST, scanf_i_octal) {
+ int i;
+ EXPECT_EQ(1, sscanf("<01234567>", "<%i>", &i));
+ EXPECT_EQ(01234567, i);
+
+ long long int lli;
+ char ch;
+ EXPECT_EQ(2, sscanf("010234567890abcdefg", "%lli%c", &lli, &ch));
+ EXPECT_EQ(010234567, lli);
+ EXPECT_EQ('8', ch);
+}
+
+TEST(STDIO_TEST, scanf_i_binary) {
+ int i;
+ EXPECT_EQ(1, sscanf("<0b101>", "<%i>", &i));
+ EXPECT_EQ(0b101, i);
+
+ long long int lli;
+ char ch;
+ EXPECT_EQ(2, sscanf("0b10234567890abcdefg", "%lli%c", &lli, &ch));
+ EXPECT_EQ(0b10, lli);
+ EXPECT_EQ('2', ch);
+}
+
+TEST(STDIO_TEST, wscanf_i_decimal) {
+ int i;
+ EXPECT_EQ(1, swscanf(L"<123789>", L"<%i>", &i));
+ EXPECT_EQ(123789, i);
+
+ long long int lli;
+ char ch;
+ EXPECT_EQ(2, swscanf(L"1234567890abcdefg", L"%lli%c", &lli, &ch));
+ EXPECT_EQ(1234567890, lli);
+ EXPECT_EQ('a', ch);
+}
+
+TEST(STDIO_TEST, wscanf_i_hex) {
+ int i;
+ EXPECT_EQ(1, swscanf(L"<0x123abf>", L"<%i>", &i));
+ EXPECT_EQ(0x123abf, i);
+
+ long long int lli;
+ char ch;
+ EXPECT_EQ(2, swscanf(L"0x1234567890abcdefg", L"%lli%c", &lli, &ch));
+ EXPECT_EQ(0x1234567890abcdefLL, lli);
+ EXPECT_EQ('g', ch);
+}
+
+TEST(STDIO_TEST, wscanf_i_octal) {
+ int i;
+ EXPECT_EQ(1, swscanf(L"<01234567>", L"<%i>", &i));
+ EXPECT_EQ(01234567, i);
+
+ long long int lli;
+ char ch;
+ EXPECT_EQ(2, swscanf(L"010234567890abcdefg", L"%lli%c", &lli, &ch));
+ EXPECT_EQ(010234567, lli);
+ EXPECT_EQ('8', ch);
+}
+
+TEST(STDIO_TEST, wscanf_i_binary) {
+ int i;
+ EXPECT_EQ(1, swscanf(L"<0b101>", L"<%i>", &i));
+ EXPECT_EQ(0b101, i);
+
+ long long int lli;
+ char ch;
+ EXPECT_EQ(2, swscanf(L"0b10234567890abcdefg", L"%lli%c", &lli, &ch));
+ EXPECT_EQ(0b10, lli);
+ EXPECT_EQ('2', ch);
+}
+
+TEST(STDIO_TEST, scanf_b) {
+ // Our clang doesn't know about %b yet.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int i;
+ char ch;
+ EXPECT_EQ(2, sscanf("<1012>", "<%b%c>", &i, &ch));
+ EXPECT_EQ(0b101, i);
+ EXPECT_EQ('2', ch);
+ EXPECT_EQ(1, sscanf("<00000101>", "<%08b>", &i));
+ EXPECT_EQ(0b00000101, i);
+ EXPECT_EQ(1, sscanf("<0b1010>", "<%b>", &i));
+ EXPECT_EQ(0b1010, i);
+ EXPECT_EQ(2, sscanf("-0b", "%i%c", &i, &ch));
+ EXPECT_EQ(0, i);
+ EXPECT_EQ('b', ch);
+#pragma clang diagnostic pop
+}
+
+TEST(STDIO_TEST, swscanf_b) {
+ // Our clang doesn't know about %b yet.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat"
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+ int i;
+ char ch;
+ EXPECT_EQ(2, swscanf(L"<1012>", L"<%b%c>", &i, &ch));
+ EXPECT_EQ(0b101, i);
+ EXPECT_EQ('2', ch);
+ EXPECT_EQ(1, swscanf(L"<00000101>", L"<%08b>", &i));
+ EXPECT_EQ(0b00000101, i);
+ EXPECT_EQ(1, swscanf(L"<0b1010>", L"<%b>", &i));
+ EXPECT_EQ(0b1010, i);
+ EXPECT_EQ(2, swscanf(L"-0b", L"%i%c", &i, &ch));
+ EXPECT_EQ(0, i);
+ EXPECT_EQ('b', ch);
+#pragma clang diagnostic pop
+}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 465e61a..f507e08 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -843,11 +843,19 @@
ASSERT_EQ(T(-123), fn("-123", &end_p, 10));
ASSERT_EQ(T(123), fn("+123", &end_p, 10));
+ // If we see "0b" *not* followed by a binary digit, we shouldn't swallow the 'b'.
+ ASSERT_EQ(T(0), fn("0b", &end_p, 2));
+ ASSERT_EQ('b', *end_p);
+
+ // Binary (the "0b" prefix) is case-insensitive.
+ ASSERT_EQ(T(0b101), fn("0b101", &end_p, 0));
+ ASSERT_EQ(T(0b101), fn("0B101", &end_p, 0));
+
// 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);
- // Hexadecimal (both the 0x and the digits) is case-insensitive.
+ // Hexadecimal (both the "0x" prefix and the digits) is case-insensitive.
ASSERT_EQ(T(0xab), fn("0xab", &end_p, 0));
ASSERT_EQ(T(0xab), fn("0Xab", &end_p, 0));
ASSERT_EQ(T(0xab), fn("0xAB", &end_p, 0));
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 8d3fb68..38957e2 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -136,7 +136,7 @@
// A real-time signal.
ASSERT_STREQ("Real-time signal 14", strsignal(SIGRTMIN + 14));
// One of the signals the C library keeps to itself.
- ASSERT_STREQ("Unknown signal 32", strsignal(__SIGRTMIN));
+ ASSERT_STREQ("Unknown signal 32", strsignal(32)); // __SIGRTMIN
// Errors.
ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small.
@@ -1673,3 +1673,15 @@
ASSERT_EQ(nullptr, memccpy(dst, "hello world", ' ', 4));
ASSERT_STREQ("hell", dst);
}
+
+TEST(STRING_TEST, memset_explicit_smoke) {
+#if defined(__BIONIC__)
+ // We can't reliably test that the compiler won't optimize out calls to
+ // memset_explicit(), but we can at least check that it behaves like memset.
+ char buf[32];
+ memset_explicit(buf, 'x', sizeof(buf));
+ ASSERT_TRUE(memcmp(buf, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", sizeof(buf)) == 0);
+#else
+ GTEST_SKIP() << "memset_explicit not available";
+#endif
+}
diff --git a/tests/struct_layout_test.cpp b/tests/struct_layout_test.cpp
index 0123ed9..10c100a 100644
--- a/tests/struct_layout_test.cpp
+++ b/tests/struct_layout_test.cpp
@@ -30,7 +30,7 @@
#define CHECK_OFFSET(name, field, offset) \
check_offset(#name, #field, offsetof(name, field), offset);
#ifdef __LP64__
- CHECK_SIZE(pthread_internal_t, 776);
+ CHECK_SIZE(pthread_internal_t, 784);
CHECK_OFFSET(pthread_internal_t, next, 0);
CHECK_OFFSET(pthread_internal_t, prev, 8);
CHECK_OFFSET(pthread_internal_t, tid, 16);
@@ -55,6 +55,7 @@
CHECK_OFFSET(pthread_internal_t, dlerror_buffer, 248);
CHECK_OFFSET(pthread_internal_t, bionic_tls, 760);
CHECK_OFFSET(pthread_internal_t, errno_value, 768);
+ CHECK_OFFSET(pthread_internal_t, vfork_child_stack_bottom, 776);
CHECK_SIZE(bionic_tls, 12200);
CHECK_OFFSET(bionic_tls, key_data, 0);
CHECK_OFFSET(bionic_tls, locale, 2080);
@@ -72,7 +73,7 @@
CHECK_OFFSET(bionic_tls, bionic_systrace_disabled, 12193);
CHECK_OFFSET(bionic_tls, padding, 12194);
#else
- CHECK_SIZE(pthread_internal_t, 668);
+ CHECK_SIZE(pthread_internal_t, 672);
CHECK_OFFSET(pthread_internal_t, next, 0);
CHECK_OFFSET(pthread_internal_t, prev, 4);
CHECK_OFFSET(pthread_internal_t, tid, 8);
@@ -97,6 +98,7 @@
CHECK_OFFSET(pthread_internal_t, dlerror_buffer, 148);
CHECK_OFFSET(pthread_internal_t, bionic_tls, 660);
CHECK_OFFSET(pthread_internal_t, errno_value, 664);
+ CHECK_OFFSET(pthread_internal_t, vfork_child_stack_bottom, 668);
CHECK_SIZE(bionic_tls, 11080);
CHECK_OFFSET(bionic_tls, key_data, 0);
CHECK_OFFSET(bionic_tls, locale, 1040);
diff --git a/tests/sys_sysinfo_test.cpp b/tests/sys_sysinfo_test.cpp
index cca2f44..69656ad 100644
--- a/tests/sys_sysinfo_test.cpp
+++ b/tests/sys_sysinfo_test.cpp
@@ -43,7 +43,7 @@
memset(&si, 0, sizeof(si));
ASSERT_EQ(0, sysinfo(&si));
- ASSERT_GT(si.uptime, 10); // You're not running CTS within 10s of booting!
+ ASSERT_GT(static_cast<long>(si.uptime), 10); // You're not running CTS within 10s of booting!
ASSERT_GT(uint64_t(si.totalram) * si.mem_unit, uint64_t(512 * 1024 * 1024));
ASSERT_GE(si.totalram, si.freeram);
ASSERT_GE(si.totalswap, si.freeswap);
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 5fc4cad..40e5c6d 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -84,6 +84,16 @@
ASSERT_EQ(1970, broken_down->tm_year + 1900);
}
+TEST(time, mktime_TZ_as_UTC_and_offset) {
+ struct tm tm = {.tm_year = 70, .tm_mon = 0, .tm_mday = 1};
+
+ // This TZ value is not a valid Olson ID and is not present in tzdata file,
+ // but is a valid TZ string according to POSIX standard.
+ setenv("TZ", "UTC+08:00:00", 1);
+ tzset();
+ ASSERT_EQ(static_cast<time_t>(8 * 60 * 60), mktime(&tm));
+}
+
static void* gmtime_no_stack_overflow_14313703_fn(void*) {
const char* original_tz = getenv("TZ");
// Ensure we'll actually have to enter tzload by using a time zone that doesn't exist.
@@ -134,15 +144,11 @@
}
TEST(time, mktime_10310929) {
- struct tm t;
- memset(&t, 0, sizeof(tm));
- t.tm_year = 200;
- t.tm_mon = 2;
- t.tm_mday = 10;
+ struct tm tm = {.tm_year = 2100 - 1900, .tm_mon = 2, .tm_mday = 10};
#if !defined(__LP64__)
// 32-bit bionic has a signed 32-bit time_t.
- ASSERT_EQ(-1, mktime(&t));
+ ASSERT_EQ(-1, mktime(&tm));
ASSERT_EQ(EOVERFLOW, errno);
#else
// Everyone else should be using a signed 64-bit time_t.
@@ -151,13 +157,12 @@
setenv("TZ", "America/Los_Angeles", 1);
tzset();
errno = 0;
- ASSERT_EQ(static_cast<time_t>(4108348800U), mktime(&t));
- ASSERT_EQ(0, errno);
- setenv("TZ", "UTC", 1);
- tzset();
- errno = 0;
- ASSERT_EQ(static_cast<time_t>(4108320000U), mktime(&t));
+ // On the date/time specified by tm America/Los_Angeles
+ // follows DST. But tm_isdst is set to 0, which forces
+ // mktime to interpret that time as local standard, hence offset
+ // is 8 hours, not 7.
+ ASSERT_EQ(static_cast<time_t>(4108348800U), mktime(&tm));
ASSERT_EQ(0, errno);
#endif
}
@@ -184,6 +189,43 @@
ASSERT_EQ(EOVERFLOW, errno);
}
+TEST(time, mktime_invalid_tm_TZ_combination) {
+ setenv("TZ", "UTC", 1);
+
+ struct tm t;
+ memset(&t, 0, sizeof(tm));
+ t.tm_year = 2022 - 1900;
+ t.tm_mon = 11;
+ t.tm_mday = 31;
+ // UTC does not observe DST
+ t.tm_isdst = 1;
+
+ errno = 0;
+
+ EXPECT_EQ(static_cast<time_t>(-1), mktime(&t));
+ // mktime sets errno to EOVERFLOW if result is unrepresentable.
+ EXPECT_EQ(EOVERFLOW, errno);
+}
+
+// Transitions in the tzdata file are generated up to the year 2100. Testing
+// that dates beyond that are handled properly too.
+TEST(time, mktime_after_2100) {
+ struct tm tm = {.tm_year = 2150 - 1900, .tm_mon = 2, .tm_mday = 10, .tm_isdst = -1};
+
+#if !defined(__LP64__)
+ // 32-bit bionic has a signed 32-bit time_t.
+ ASSERT_EQ(-1, mktime(&tm));
+ ASSERT_EQ(EOVERFLOW, errno);
+#else
+ setenv("TZ", "Europe/London", 1);
+ tzset();
+ errno = 0;
+
+ ASSERT_EQ(static_cast<time_t>(5686156800U), mktime(&tm));
+ ASSERT_EQ(0, errno);
+#endif
+}
+
TEST(time, strftime) {
setenv("TZ", "UTC", 1);
@@ -206,7 +248,25 @@
EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
}
-TEST(time, strftime_null_tm_zone) {
+TEST(time, strftime_second_before_epoch) {
+ setenv("TZ", "UTC", 1);
+
+ struct tm t;
+ memset(&t, 0, sizeof(tm));
+ t.tm_year = 1969 - 1900;
+ t.tm_mon = 11;
+ t.tm_mday = 31;
+ t.tm_hour = 23;
+ t.tm_min = 59;
+ t.tm_sec = 59;
+
+ char buf[64];
+
+ EXPECT_EQ(2U, strftime(buf, sizeof(buf), "%s", &t));
+ EXPECT_STREQ("-1", buf);
+}
+
+TEST(time, strftime_Z_null_tm_zone) {
// Netflix on Nexus Player wouldn't start (http://b/25170306).
struct tm t;
memset(&t, 0, sizeof(tm));
@@ -244,6 +304,86 @@
#endif
}
+// According to C language specification the only tm struct field needed to
+// find out replacement for %z and %Z in strftime is tm_isdst. Which is
+// wrong, as time zones change their standard offset and even DST savings.
+// tzcode deviates from C language specification and requires tm struct either
+// to be output of localtime-like functions or to be modified by mktime call
+// before passing to strftime. See tz mailing discussion for more details
+// https://mm.icann.org/pipermail/tz/2022-July/031674.html
+// But we are testing case when tm.tm_zone is null, which means that tm struct
+// is not coming from localtime and is neither modified by mktime. That's why
+// we are comparing against +0000, even though America/Los_Angeles never
+// observes it.
+TEST(time, strftime_z_null_tm_zone) {
+ char str[64];
+ struct tm tm = {.tm_year = 109, .tm_mon = 4, .tm_mday = 2, .tm_isdst = 0};
+
+ setenv("TZ", "America/Los_Angeles", 1);
+ tzset();
+
+ tm.tm_zone = NULL;
+
+ size_t result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+
+ tm.tm_isdst = 1;
+
+ result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+
+ setenv("TZ", "UTC", 1);
+ tzset();
+
+ tm.tm_isdst = 0;
+
+ result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+
+ tm.tm_isdst = 1;
+
+ result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+}
+
+TEST(time, strftime_z_Europe_Lisbon) {
+ char str[64];
+ // During 1992-1996 Europe/Lisbon standard offset was 1 hour.
+ // tm_isdst is not set as it will be overridden by mktime call anyway.
+ struct tm tm = {.tm_year = 1996 - 1900, .tm_mon = 2, .tm_mday = 13};
+
+ setenv("TZ", "Europe/Lisbon", 1);
+ tzset();
+
+ // tzcode's strftime implementation for %z relies on prior mktime call.
+ // At the moment of writing %z value is taken from tm_gmtoff. So without
+ // mktime call %z is replaced with +0000.
+ // See https://mm.icann.org/pipermail/tz/2022-July/031674.html
+ mktime(&tm);
+
+ size_t result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0100", str);
+
+ // Now standard offset is 0.
+ tm = {.tm_year = 2022 - 1900, .tm_mon = 2, .tm_mday = 13};
+
+ mktime(&tm);
+ result = strftime(str, sizeof(str), "%z", &tm);
+
+ EXPECT_EQ(5U, result);
+ EXPECT_STREQ("+0000", str);
+}
+
TEST(time, strftime_l) {
locale_t cloc = newlocale(LC_ALL, "C.UTF-8", nullptr);
locale_t old_locale = uselocale(cloc);
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 6d7e687..5fce5b8 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1103,6 +1103,10 @@
ASSERT_EQ(4, GetCpuCountFromString("0, 1-2, 4\n"));
}
+TEST(UNISTD_TEST, sysconf_SC_NPROCESSORS_make_sense) {
+ ASSERT_LE(sysconf(_SC_NPROCESSORS_ONLN), sysconf(_SC_NPROCESSORS_CONF));
+}
+
TEST(UNISTD_TEST, sysconf_SC_NPROCESSORS_ONLN) {
std::string line;
ASSERT_TRUE(android::base::ReadFileToString("/sys/devices/system/cpu/online", &line));
@@ -1648,3 +1652,41 @@
auto t1 = std::chrono::steady_clock::now();
ASSERT_GE(t1-t0, 1s);
}
+
+TEST(UNISTD_TEST, close_range) {
+#if defined(__GLIBC__)
+ GTEST_SKIP() << "glibc too old";
+#elif defined(ANDROID_HOST_MUSL)
+ GTEST_SKIP() << "musl does not have close_range";
+#else // __GLIBC__
+ int fd = open("/proc/version", O_RDONLY);
+ ASSERT_GE(fd, 0);
+
+ // Try to close the file descriptor (this requires a 5.9+ kernel)
+ if (close_range(fd, fd, 0) == 0) {
+ // we can't close it *again*
+ ASSERT_EQ(close(fd), -1);
+ ASSERT_EQ(errno, EBADF);
+ } else {
+ ASSERT_EQ(errno, ENOSYS);
+ // since close_range() failed, we can close it normally
+ ASSERT_EQ(close(fd), 0);
+ }
+#endif // __GLIBC__
+}
+
+TEST(UNISTD_TEST, copy_file_range) {
+#if defined(__GLIBC__)
+ GTEST_SKIP() << "glibc too old";
+#else // __GLIBC__
+ TemporaryFile tf;
+ ASSERT_TRUE(android::base::WriteStringToFd("hello world", tf.fd));
+ ASSERT_EQ(0, lseek(tf.fd, SEEK_SET, 0));
+ TemporaryFile tf2;
+ ASSERT_EQ(11, copy_file_range(tf.fd, NULL, tf2.fd, NULL, 11, 0));
+ ASSERT_EQ(0, lseek(tf2.fd, SEEK_SET, 0));
+ std::string content;
+ ASSERT_TRUE(android::base::ReadFdToString(tf2.fd, &content));
+ ASSERT_EQ("hello world", content);
+#endif // __GLIBC__
+}
diff --git a/tests/utils.cpp b/tests/utils.cpp
new file mode 100644
index 0000000..8258833
--- /dev/null
+++ b/tests/utils.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "utils.h"
+
+void RunGwpAsanTest(const char* test_name) {
+ ExecTestHelper eh;
+ eh.SetEnv({"GWP_ASAN_SAMPLE_RATE=1", "GWP_ASAN_PROCESS_SAMPLING=1", "GWP_ASAN_MAX_ALLOCS=40000",
+ nullptr});
+ std::string filter_arg = "--gtest_filter=";
+ filter_arg += test_name;
+ std::string exec(testing::internal::GetArgvs()[0]);
+ eh.SetArgs({exec.c_str(), "--gtest_also_run_disabled_tests", filter_arg.c_str(), nullptr});
+ eh.Run([&]() { execve(exec.c_str(), eh.GetArgs(), eh.GetEnv()); },
+ /* expected_exit_status */ 0,
+ // |expected_output_regex|, ensure at least one test ran:
+ R"(\[ PASSED \] [1-9][0-9]* test)");
+}
+
+void RunSubtestNoEnv(const char* test_name) {
+ ExecTestHelper eh;
+ std::string filter_arg = "--gtest_filter=";
+ filter_arg += test_name;
+ std::string exec(testing::internal::GetArgvs()[0]);
+ eh.SetArgs({exec.c_str(), "--gtest_also_run_disabled_tests", filter_arg.c_str(), nullptr});
+ eh.Run([&]() { execve(exec.c_str(), eh.GetArgs(), eh.GetEnv()); },
+ /* expected_exit_status */ 0,
+ // |expected_output_regex|, ensure at least one test ran:
+ R"(\[ PASSED \] [1-9]+0? test)");
+}
diff --git a/tests/utils.h b/tests/utils.h
index 72214c2..81869e3 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -19,6 +19,7 @@
#include <dirent.h>
#include <dlfcn.h>
#include <fcntl.h>
+#include <gtest/gtest.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/prctl.h>
@@ -264,6 +265,7 @@
};
void RunGwpAsanTest(const char* test_name);
+void RunSubtestNoEnv(const char* test_name);
#endif
class FdLeakChecker {
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 85a75ec..16d4348 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -460,6 +460,7 @@
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);
+ TestSingleWcsToInt(fn, L"0b1011", 0, static_cast<T>(0b1011), 6);
}
template <typename T>
diff --git a/tools/Android.bp b/tools/Android.bp
index dcd2a7d..d3ca28a 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -15,7 +15,7 @@
subdirs = ["*"]
-filegroup {
- name: "bionic-generate-version-script",
+python_binary_host {
+ name: "generate-version-script",
srcs: ["generate-version-script.py"],
}
diff --git a/tools/generate-version-script.py b/tools/generate-version-script.py
index def621e..fab46b9 100755
--- a/tools/generate-version-script.py
+++ b/tools/generate-version-script.py
@@ -8,7 +8,7 @@
import sys
def has_arch_tags(tags):
- for arch in ["arm", "arm64", "x86", "x86_64"]:
+ for arch in ["arm", "arm64", "riscv64", "x86", "x86_64"]:
if arch in tags:
return True
return False
diff --git a/tools/versioner/src/Arch.cpp b/tools/versioner/src/Arch.cpp
index 3a27a6e..d4d0208 100644
--- a/tools/versioner/src/Arch.cpp
+++ b/tools/versioner/src/Arch.cpp
@@ -28,6 +28,9 @@
case Arch::arm64:
return "arm64";
+ case Arch::riscv64:
+ return "riscv64";
+
case Arch::x86:
return "x86";
@@ -41,6 +44,7 @@
static const std::unordered_map<std::string, Arch> arch_name_map{
{"arm", Arch::arm},
{"arm64", Arch::arm64},
+ {"riscv64", Arch::riscv64},
{"x86", Arch::x86},
{"x86_64", Arch::x86_64},
};
diff --git a/tools/versioner/src/Arch.h b/tools/versioner/src/Arch.h
index 74d0f8f..fd98abc 100644
--- a/tools/versioner/src/Arch.h
+++ b/tools/versioner/src/Arch.h
@@ -28,6 +28,7 @@
enum class Arch : size_t {
arm = 0,
arm64,
+ riscv64,
x86,
x86_64,
};
@@ -121,6 +122,7 @@
static const std::set<Arch> supported_archs = {
Arch::arm,
Arch::arm64,
+ Arch::riscv64,
Arch::x86,
Arch::x86_64,
};
@@ -128,17 +130,19 @@
static ArchMap<std::string> arch_targets = {
{ Arch::arm, "arm-linux-androideabi" },
{ Arch::arm64, "aarch64-linux-android" },
+ { Arch::riscv64, "riscv64-linux-android" },
{ Arch::x86, "i686-linux-android" },
{ Arch::x86_64, "x86_64-linux-android" },
};
static const std::set<int> default_levels = {
- 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30,
+ 14, 15, 16, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34,
};
static const ArchMap<int> arch_min_api = {
{ Arch::arm, 9 },
{ Arch::arm64, 21 },
+ { Arch::riscv64, 10000 },
{ Arch::x86, 9 },
{ Arch::x86_64, 21 },
};
@@ -160,4 +164,7 @@
{"P", 28},
{"Q", 29},
{"R", 30},
+ {"S", 31},
+ {"T", 33},
+ {"U", 34},
};
diff --git a/tools/versioner/src/DeclarationDatabase.cpp b/tools/versioner/src/DeclarationDatabase.cpp
index ec2e38d..a029c3b 100644
--- a/tools/versioner/src/DeclarationDatabase.cpp
+++ b/tools/versioner/src/DeclarationDatabase.cpp
@@ -170,6 +170,7 @@
&arch_availability[Arch::x86].introduced } },
{ "introduced_in_64",
{ &arch_availability[Arch::arm64].introduced,
+ &arch_availability[Arch::riscv64].introduced,
&arch_availability[Arch::x86_64].introduced } },
};
diff --git a/tools/versioner/src/Preprocessor.cpp b/tools/versioner/src/Preprocessor.cpp
index eb88c46..14f80d8 100644
--- a/tools/versioner/src/Preprocessor.cpp
+++ b/tools/versioner/src/Preprocessor.cpp
@@ -141,11 +141,12 @@
static const std::vector<std::pair<std::string, std::set<Arch>>> arch_sets = {
{ "", supported_archs },
{ "!defined(__LP64__)", { Arch::arm, Arch::x86 } },
- { "defined(__LP64__)", { Arch::arm64, Arch::x86_64 } },
+ { "defined(__LP64__)", { Arch::arm64, Arch::riscv64, Arch::x86_64 } },
};
std::map<Arch, std::string> individual_archs = {
{ Arch::arm, "defined(__arm__)" },
{ Arch::arm64, "defined(__aarch64__)" },
+ { Arch::riscv64, "defined(__riscv)" },
{ Arch::x86, "defined(__i386__)" },
{ Arch::x86_64, "defined(__x86_64__)" },
};
diff --git a/tools/versioner/src/versioner.h b/tools/versioner/src/versioner.h
index e9c4989..225e14b 100644
--- a/tools/versioner/src/versioner.h
+++ b/tools/versioner/src/versioner.h
@@ -39,5 +39,5 @@
{ "sys/_system_properties.h", supported_archs },
// time64.h #errors when included on LP64 archs.
- { "time64.h", { Arch::arm64, Arch::x86_64 } },
+ { "time64.h", { Arch::arm64, Arch::riscv64, Arch::x86_64 } },
};