Hi all, This change enhances the Java foreign functions and memory API to allow users to inject thread-locals before a downcall.
The lvalue `errno` is used for error handling in C. The C11 (draft) standard gives the following use-case example: > Thus, a program that uses errnofor error checking should set it to zero > before a library function call, then inspect it before a subsequent library function call. Of course, a library function can save the value of errno on entry and then set it to zero, as long as the original value is restored if errno’s value is still zero just before the return. In the present day, it is possible to retrieve `errno` by using the API provided by `Linker.Option captureCallState`. This provides the Java-user a memory segment for thread-local data, that is populated by the JVM. The memory segment can be read using conventional FFM means, such as with a `VarHandle`. However, the contents of this segment is not used to populate the thread local data _before_ the downcall. As an example, in Java using the FFM API, an end user calling `strtol` and checking for `ERANGE` would do the following (in-line with the C standard footnote): set the captured call state buffer's `errno` to zero, perform a downcall, and then read the captured call state again to check if `errno` is still zero. While the memory segment sees `errno=0`, this is not actually written to the thread before execution. Thus, it is possible to observe stale or irrelevant error numbers. In this example, one could observe `ENOENT` after the `strtol` call, which is incorrect behaviour. This PR flushes the captured call state to the thread local variables before the downcall, ensuring that procedures in accordance to the C standard are possible. Since this was somewhat invasive, I ported it to non-Oracle platforms as well. One thing worth noting is that the setting and retrieving of thread local data is now coupled. Meaning, if a user wants to retrieve e.g. `errno` after a downcall, it is their responsibility to ensure that `errno` is appropriately set beforehand in order to make a meaningful comparison with predetermined error ranges. Testing: tiers 1-4 on Linux (x64, AArch64), macOS (x64, AArch64) and Windows (x64). I have built the JDK and run a [minimal but representative](https://gist.github.com/Arraying/41db1b093dfa5cc4bc49f1213584d520) test case on Oracle Linux 10 (x64) with Zero (native), s390x, powerpc64le and riscv64 (all QEMU). I've smoke tested these platforms in good faith, but it would be good if porters with access to actual hardware could ensure that this change is sound. I would recommend running `:jdk_foreign` or `tier1`, at least. I will work on the CSR once the code changes and new specification have received sufficient review/feedback. ------------- Commit messages: - Copyright. - Copyright. - Improve test coverage. - New JavaDoc. - Port to RISC-V. - Port to PowerPC. - Port to s390. - Port to Zero. - Port to x86_64. - Fix comment order. - ... and 3 more: https://git.openjdk.org/jdk/compare/56060367...9e48fa35 Changes: https://git.openjdk.org/jdk/pull/30059/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=30059&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8378559 Stats: 319 lines in 11 files changed: 223 ins; 7 del; 89 mod Patch: https://git.openjdk.org/jdk/pull/30059.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/30059/head:pull/30059 PR: https://git.openjdk.org/jdk/pull/30059
