-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding unwinding support for x86_64_fortanix_unknown_sgx target. #56979
Adding unwinding support for x86_64_fortanix_unknown_sgx target. #56979
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
b9b9f72
to
885cf2a
Compare
@bors: r+ |
📌 Commit 885cf2a has been approved by |
@bors: rollup |
…nd-support, r=alexcrichton Adding unwinding support for x86_64_fortanix_unknown_sgx target. Unwinding support is provided by our port of LLVM's libunwind which is available from https://github.com/fortanix/libunwind/tree/release_50. libunwind requires support for rwlock and printing to stderr, which is only provided by `std` for this target. This poses two problems: 1) how to expose the `std` functionality to C and 2) dependency inversion. ### Exposing `std` For exposing the functionality we chose to expose the following symbols: * __rust_rwlock_rdlock * __rust_rwlock_wrlock * __rust_rwlock_unlock * __rust_print_err * __rust_abort Also, the following are needed from `alloc`: * __rust_alloc * __rust_dealloc #### Rust RWLock in C In `libunwind`, RWLock is initialized as a templated static variable: ```c pthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER; ``` I don't know of a good way to use the Rust sys::rwlock::RWLock type and initializer there. We could have a static global variable in Rust, but that doesn't work with the templating. The variable needs to be initialized statically, since this target doesn't support the .init section. Currently, I just used a byte array and standard C array initialization. The mapping between this C type and the Rust type needs to be manually maintained. There is a compile-time check and a unit test to make sure the Rust versions of these C definitions match the actual Rust type. If any reviewer knows of a better solution, please do tell. ### Dependency inversion issue `std` depends on `panic_unwind` which depends on `libunwind`, and `libunwind` depends on `std`. This is not normally supported by Rust's linking system. Therefore we use raw C exports from `std` *and* `libunwind.a` is linked last in the target `post_link_objects` instead of being built as part of the Rust `libunwind`. Currently, all C exports are defined in `src/libstd/sys/sgx/rwlock.rs` to overcome LTO issues. Only the `__rust_rwlock_*` definitions *need* to live there for privacy reasons. Once again, if any reviewer knows of a better solution, please do tell. r? @alexcrichton
…nd-support, r=alexcrichton Adding unwinding support for x86_64_fortanix_unknown_sgx target. Unwinding support is provided by our port of LLVM's libunwind which is available from https://github.com/fortanix/libunwind/tree/release_50. libunwind requires support for rwlock and printing to stderr, which is only provided by `std` for this target. This poses two problems: 1) how to expose the `std` functionality to C and 2) dependency inversion. ### Exposing `std` For exposing the functionality we chose to expose the following symbols: * __rust_rwlock_rdlock * __rust_rwlock_wrlock * __rust_rwlock_unlock * __rust_print_err * __rust_abort Also, the following are needed from `alloc`: * __rust_alloc * __rust_dealloc #### Rust RWLock in C In `libunwind`, RWLock is initialized as a templated static variable: ```c pthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER; ``` I don't know of a good way to use the Rust sys::rwlock::RWLock type and initializer there. We could have a static global variable in Rust, but that doesn't work with the templating. The variable needs to be initialized statically, since this target doesn't support the .init section. Currently, I just used a byte array and standard C array initialization. The mapping between this C type and the Rust type needs to be manually maintained. There is a compile-time check and a unit test to make sure the Rust versions of these C definitions match the actual Rust type. If any reviewer knows of a better solution, please do tell. ### Dependency inversion issue `std` depends on `panic_unwind` which depends on `libunwind`, and `libunwind` depends on `std`. This is not normally supported by Rust's linking system. Therefore we use raw C exports from `std` *and* `libunwind.a` is linked last in the target `post_link_objects` instead of being built as part of the Rust `libunwind`. Currently, all C exports are defined in `src/libstd/sys/sgx/rwlock.rs` to overcome LTO issues. Only the `__rust_rwlock_*` definitions *need* to live there for privacy reasons. Once again, if any reviewer knows of a better solution, please do tell. r? @alexcrichton
…nd-support, r=alexcrichton Adding unwinding support for x86_64_fortanix_unknown_sgx target. Unwinding support is provided by our port of LLVM's libunwind which is available from https://github.com/fortanix/libunwind/tree/release_50. libunwind requires support for rwlock and printing to stderr, which is only provided by `std` for this target. This poses two problems: 1) how to expose the `std` functionality to C and 2) dependency inversion. ### Exposing `std` For exposing the functionality we chose to expose the following symbols: * __rust_rwlock_rdlock * __rust_rwlock_wrlock * __rust_rwlock_unlock * __rust_print_err * __rust_abort Also, the following are needed from `alloc`: * __rust_alloc * __rust_dealloc #### Rust RWLock in C In `libunwind`, RWLock is initialized as a templated static variable: ```c pthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER; ``` I don't know of a good way to use the Rust sys::rwlock::RWLock type and initializer there. We could have a static global variable in Rust, but that doesn't work with the templating. The variable needs to be initialized statically, since this target doesn't support the .init section. Currently, I just used a byte array and standard C array initialization. The mapping between this C type and the Rust type needs to be manually maintained. There is a compile-time check and a unit test to make sure the Rust versions of these C definitions match the actual Rust type. If any reviewer knows of a better solution, please do tell. ### Dependency inversion issue `std` depends on `panic_unwind` which depends on `libunwind`, and `libunwind` depends on `std`. This is not normally supported by Rust's linking system. Therefore we use raw C exports from `std` *and* `libunwind.a` is linked last in the target `post_link_objects` instead of being built as part of the Rust `libunwind`. Currently, all C exports are defined in `src/libstd/sys/sgx/rwlock.rs` to overcome LTO issues. Only the `__rust_rwlock_*` definitions *need* to live there for privacy reasons. Once again, if any reviewer knows of a better solution, please do tell. r? @alexcrichton
Rollup of 20 pull requests Successful merges: - #56802 (Add DoubleEndedIterator::nth_back) - #56842 (Add unstable VecDeque::rotate_{left|right}) - #56869 (Reduce search-index.js size) - #56887 (Disable field reordering for repr(int).) - #56892 (rustc: Update Clang used to build LLVM on Linux) - #56909 (static eval: Do not ICE on layout size overflow) - #56914 (Ignore ui/target-feature-gate on sparc, sparc64, powerpc, powerpc64 and powerpc64le) - #56917 (Simplify MIR generation for logical operations) - #56919 (Remove a wrong multiplier on relocation offset computation) - #56933 (Add --progress to git submodule commands in x.py) - #56941 (deny intra-doc link resolution failures in libstd) - #56964 (Remove `TokenStream::JointTree`.) - #56970 (Mem uninit doc ptr drop) - #56973 (make basic CTFE tracing available on release builds) - #56979 (Adding unwinding support for x86_64_fortanix_unknown_sgx target.) - #56981 (miri: allocation is infallible) - #56984 (A few tweaks to dropck_outlives) - #56989 (Fix compiletest `trim` deprecation warnings) - #56992 (suggest similar lint names for unknown lints) - #57002 (Stabilize Vec(Deque)::resize_with) Failed merges: r? @ghost
Rollup of 20 pull requests Successful merges: - #56802 (Add DoubleEndedIterator::nth_back) - #56842 (Add unstable VecDeque::rotate_{left|right}) - #56869 (Reduce search-index.js size) - #56887 (Disable field reordering for repr(int).) - #56892 (rustc: Update Clang used to build LLVM on Linux) - #56909 (static eval: Do not ICE on layout size overflow) - #56914 (Ignore ui/target-feature-gate on sparc, sparc64, powerpc, powerpc64 and powerpc64le) - #56917 (Simplify MIR generation for logical operations) - #56919 (Remove a wrong multiplier on relocation offset computation) - #56933 (Add --progress to git submodule commands in x.py) - #56941 (deny intra-doc link resolution failures in libstd) - #56964 (Remove `TokenStream::JointTree`.) - #56970 (Mem uninit doc ptr drop) - #56973 (make basic CTFE tracing available on release builds) - #56979 (Adding unwinding support for x86_64_fortanix_unknown_sgx target.) - #56981 (miri: allocation is infallible) - #56984 (A few tweaks to dropck_outlives) - #56989 (Fix compiletest `trim` deprecation warnings) - #56992 (suggest similar lint names for unknown lints) - #57002 (Stabilize Vec(Deque)::resize_with) Failed merges: r? @ghost
…nd-support, r=alexcrichton Adding unwinding support for x86_64_fortanix_unknown_sgx target. Unwinding support is provided by our port of LLVM's libunwind which is available from https://github.com/fortanix/libunwind/tree/release_50. libunwind requires support for rwlock and printing to stderr, which is only provided by `std` for this target. This poses two problems: 1) how to expose the `std` functionality to C and 2) dependency inversion. ### Exposing `std` For exposing the functionality we chose to expose the following symbols: * __rust_rwlock_rdlock * __rust_rwlock_wrlock * __rust_rwlock_unlock * __rust_print_err * __rust_abort Also, the following are needed from `alloc`: * __rust_alloc * __rust_dealloc #### Rust RWLock in C In `libunwind`, RWLock is initialized as a templated static variable: ```c pthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER; ``` I don't know of a good way to use the Rust sys::rwlock::RWLock type and initializer there. We could have a static global variable in Rust, but that doesn't work with the templating. The variable needs to be initialized statically, since this target doesn't support the .init section. Currently, I just used a byte array and standard C array initialization. The mapping between this C type and the Rust type needs to be manually maintained. There is a compile-time check and a unit test to make sure the Rust versions of these C definitions match the actual Rust type. If any reviewer knows of a better solution, please do tell. ### Dependency inversion issue `std` depends on `panic_unwind` which depends on `libunwind`, and `libunwind` depends on `std`. This is not normally supported by Rust's linking system. Therefore we use raw C exports from `std` *and* `libunwind.a` is linked last in the target `post_link_objects` instead of being built as part of the Rust `libunwind`. Currently, all C exports are defined in `src/libstd/sys/sgx/rwlock.rs` to overcome LTO issues. Only the `__rust_rwlock_*` definitions *need* to live there for privacy reasons. Once again, if any reviewer knows of a better solution, please do tell. r? @alexcrichton
…nd-support, r=alexcrichton Adding unwinding support for x86_64_fortanix_unknown_sgx target. Unwinding support is provided by our port of LLVM's libunwind which is available from https://github.com/fortanix/libunwind/tree/release_50. libunwind requires support for rwlock and printing to stderr, which is only provided by `std` for this target. This poses two problems: 1) how to expose the `std` functionality to C and 2) dependency inversion. ### Exposing `std` For exposing the functionality we chose to expose the following symbols: * __rust_rwlock_rdlock * __rust_rwlock_wrlock * __rust_rwlock_unlock * __rust_print_err * __rust_abort Also, the following are needed from `alloc`: * __rust_alloc * __rust_dealloc #### Rust RWLock in C In `libunwind`, RWLock is initialized as a templated static variable: ```c pthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER; ``` I don't know of a good way to use the Rust sys::rwlock::RWLock type and initializer there. We could have a static global variable in Rust, but that doesn't work with the templating. The variable needs to be initialized statically, since this target doesn't support the .init section. Currently, I just used a byte array and standard C array initialization. The mapping between this C type and the Rust type needs to be manually maintained. There is a compile-time check and a unit test to make sure the Rust versions of these C definitions match the actual Rust type. If any reviewer knows of a better solution, please do tell. ### Dependency inversion issue `std` depends on `panic_unwind` which depends on `libunwind`, and `libunwind` depends on `std`. This is not normally supported by Rust's linking system. Therefore we use raw C exports from `std` *and* `libunwind.a` is linked last in the target `post_link_objects` instead of being built as part of the Rust `libunwind`. Currently, all C exports are defined in `src/libstd/sys/sgx/rwlock.rs` to overcome LTO issues. Only the `__rust_rwlock_*` definitions *need* to live there for privacy reasons. Once again, if any reviewer knows of a better solution, please do tell. r? @alexcrichton
Rollup of 25 pull requests Successful merges: - #56802 (Add DoubleEndedIterator::nth_back) - #56909 (static eval: Do not ICE on layout size overflow) - #56914 (Ignore ui/target-feature-gate on sparc, sparc64, powerpc, powerpc64 and powerpc64le) - #56919 (Remove a wrong multiplier on relocation offset computation) - #56933 (Add --progress to git submodule commands in x.py) - #56936 (rename div_euc -> div_euclid, and mod_euc -> rem_euclid) - #56941 (deny intra-doc link resolution failures in libstd) - #56945 (Fix rustdoc-js tests) - #56967 (Replace current crate's searchIndex when regenerating) - #56970 (Mem uninit doc ptr drop) - #56973 (make basic CTFE tracing available on release builds) - #56979 (Adding unwinding support for x86_64_fortanix_unknown_sgx target.) - #56981 (miri: allocation is infallible) - #56984 (A few tweaks to dropck_outlives) - #56989 (Fix compiletest `trim` deprecation warnings) - #56992 (suggest similar lint names for unknown lints) - #57002 (Stabilize Vec(Deque)::resize_with) - #57011 (rustdoc: add new CLI flag to load static files from a different location) - #57027 (Optimize away a move) - #57034 (Inline tweaks) - #57039 (Update migrate warning wording.) - #57040 (Fix feature gate to point to 1.32.0 for `path_from_str`) - #57049 (Stabilize #[repr(packed(N))]) - #57050 (Fixed typo in HashMap documentation) - #57052 (Fix stabilization version numbers (exhaustive_integer_patterns + macro_literal_matcher))
…ix-unknown-sgx-backtrace-support, r=alexcrichton Supporting backtrace for x86_64-fortanix-unknown-sgx. # Overview Implementing following functions required by `libstd/sys_common` to support `backtrace`: ``` 1. unwind_backtrace 2. trace_fn 3. resolve_symname ``` # Description: The changes here are quite similar to the Cloudabi target `src/libstd/sys/cloudabi/backtrace.rs` The first 2 functions are implemented via calls to libunwind.a that is linked to the `x86_64-fortanix-unknown-sgx` (rust-lang#56979), we have not implemented functionality needed by `resolve_symname` (or `dladdr`) to reduce SGX TCB. Rather, we print the function address (relative to enclave image base) in `resolve_symname` which can be later translated to correct symbol name (say, via `addr2line`). # Note: For `x86_64-fortanix-unknown-sgx`, the `RUST_BACKTRACE` environment has to be set from within the program running in an enclave. cc: @jethrogb r? @alexcrichton
…sgx-tier2_support, r=alexcrichton Upgrade x86_64-fortanix-unknown-sgx platform support to tier 2 ## Overview 1. This PR upgrades x86_64-fortanix-unknown-sgx platform support to tier 2 (std only) by setting up build automation for this target. 1. For supporting unwinding, this target needs to link to a port of LLVM's libunwind (more details could be found in #56979), which will be distributed along with the Rust binaries (similar to the extra musl objects) ### Building and copying libunwind: We have added a new build script (`build-x86_64-fortanix-unknown-sgx-toolchain.sh`) that will run while the container is built. This will build `libunwind.a` from git source. While the container is built, the persistent volumes where obj/ gets created aren't yet mapped. As a workaround, we copy the built `libunwind.a` to `obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-fortanix-unknown-sgx/lib/` after x.py runs. If any reviewer knows of a better solution, please do tell. r? @Mark-Simulacrum
Unwinding support is provided by our port of LLVM's libunwind which is available from https://github.com/fortanix/libunwind/tree/release_50.
libunwind requires support for rwlock and printing to stderr, which is only provided by
std
for this target. This poses two problems: 1) how to expose thestd
functionality to C and 2) dependency inversion.Exposing
std
For exposing the functionality we chose to expose the following symbols:
Also, the following are needed from
alloc
:Rust RWLock in C
In
libunwind
, RWLock is initialized as a templated static variable:I don't know of a good way to use the Rust sys::rwlock::RWLock type and initializer there. We could have a static global variable in Rust, but that doesn't work with the templating. The variable needs to be initialized statically, since this target doesn't support the .init section. Currently, I just used a byte array and standard C array initialization. The mapping between this C type and the Rust type needs to be manually maintained. There is a compile-time check and a unit test to make sure the Rust versions of these C definitions match the actual Rust type. If any reviewer knows of a better solution, please do tell.
Dependency inversion issue
std
depends onpanic_unwind
which depends onlibunwind
, andlibunwind
depends onstd
. This is not normally supported by Rust's linking system. Therefore we use raw C exports fromstd
andlibunwind.a
is linked last in the targetpost_link_objects
instead of being built as part of the Rustlibunwind
. Currently, all C exports are defined insrc/libstd/sys/sgx/rwlock.rs
to overcome LTO issues. Only the__rust_rwlock_*
definitions need to live there for privacy reasons. Once again, if any reviewer knows of a better solution, please do tell.r? @alexcrichton