Create personality stub function for no_std panic=abort crates#137854
Draft
Noratrieb wants to merge 1 commit intorust-lang:mainfrom
Draft
Create personality stub function for no_std panic=abort crates#137854Noratrieb wants to merge 1 commit intorust-lang:mainfrom
Noratrieb wants to merge 1 commit intorust-lang:mainfrom
Conversation
This comment has been minimized.
This comment has been minimized.
**This is a very WIP state. It has no tests, no platform gates, and
probably many bugs.**
Every crate that may unwind (being compiled with panic=unwind) needs a reference to a personality function in its object code.
The personality function is defined in `std`. For crates downstream of `std` (with `std` in the cstore), they will resolve to the personality lang item of std and reference that function from there (using its symbol_name `rust_eh_personality`).
For `#![no_std]` crates, they will also reference the `rust_eh_personality` symbol (directly, not via weak lang item machinery).
But when `std` is never linked into a crate graph containing panic=unwind crates (which happens on all panic=unwind default targets because of core), the symbol isn't present and we get a linker error.
This PR solves this problem by injecting a stub for
`rust_eh_personality` into the final link of binaries where the previous
conditions were fulfilled. This is implemented in a way that's very
similar to the allocator shim.
Because we don't want to insta-stabilize this functionality, the stub
doesn't just abort, it will first do a volatile read of the
`__rust_personality_stub_is_unstable` symbol (once again similar to the
allocator) to ensure that this functionality cannot be relied on without
providing this symbol.
Example code that now works on x86_64-unknown-linux-gnu:
```rust
fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! {
loop {}
}
unsafe extern "C" {
fn write(fd: i32, buf: *const u8, count: usize);
}
static __rust_personality_stub_is_unstable: u8 = 0;
fn main() -> i32 {
// bring in some code that requires the personality function
[1].sort_unstable();
let msg = b"meow\n";
unsafe {
write(1, msg.as_ptr(), msg.len());
}
0
}
```
When compiled with `-Cpanic=abort`, this would previously result in a
linker error because the `rust_eh_personality` symbol was not found.
Now, it compiles and runs successfully.
63622a8 to
a074676
Compare
Collaborator
|
The job Click to see the possible cause of the failure (guessed by this bot) |
Collaborator
|
☔ The latest upstream changes (presumably #127173) made this pull request unmergeable. Please resolve the merge conflicts. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a very WIP state. It has no tests, no platform gates, and probably many bugs.
I'm opening this PR mostly as a proof of concept.
Every crate that may unwind (being compiled with panic=unwind) needs a reference to a personality function in its object code.
The personality function is defined in
std. For crates downstream ofstd(withstdin the cstore), they will resolve to the personality lang item of std and reference that function from there (using its symbol_namerust_eh_personality).For
#![no_std]crates, they will also reference therust_eh_personalitysymbol (directly, not via weak lang item machinery).But when
stdis never linked into a crate graph containing panic=unwind crates (which happens on all panic=unwind default targets because of core), the symbol isn't present and we get a linker error.This PR solves this problem by injecting a stub for
rust_eh_personalityinto the final link of binaries where the previous conditions were fulfilled. This is implemented in a way that's very similar to the allocator shim.Because we don't want to insta-stabilize this functionality, the stub doesn't just abort, it will first do a volatile read of the
__rust_personality_stub_is_unstablesymbol (once again similar to the allocator) to ensure that this functionality cannot be relied on without providing this symbol.Example code that now works on x86_64-unknown-linux-gnu:
When compiled with
-Cpanic=abort, this would previously result in a linker error because therust_eh_personalitysymbol was not found. Now, it compiles and runs successfully.r? @ghost
random notes:
__rust_personality_stub_is_unstablefrom rust dylibs