Skip to content

Mangle personality symbol#148413

Open
Noratrieb wants to merge 1 commit intorust-lang:mainfrom
Noratrieb:mangle-rust-eh-personality
Open

Mangle personality symbol#148413
Noratrieb wants to merge 1 commit intorust-lang:mainfrom
Noratrieb:mangle-rust-eh-personality

Conversation

@Noratrieb
Copy link
Member

@Noratrieb Noratrieb commented Nov 2, 2025

Previously, std-internal symbols (like __rust_alloc or rust_panic) were changed to now be mangled via a v0 scheme with the compiler version hash (_RNvCs4CIB29Id3dw_7___rustc10rust_panic) to make it possible to have multiple staticlibs (as long as they have different version hashes) in the same program without symbol conflicts. But the personality function remained unmangled, because LLVM hardcodes that name.

I made a change in LLVM llvm/llvm-project#166095 that makes LLVM now check the suffix instead of an exact match, so we can mangle the personality function with this scheme.

This removes the last completely unmangled symbol from Rust staticlibs! (though the mangling is still quite weak, so it's still not as nice as it would ideally be).

Before, on a trivial staticlib:

readelf -s liblib.a | rg GLOBAL | rg -v " UND | HIDDEN " | rg -v ' _ZN'
     8: 0000000000000000     5 FUNC    GLOBAL DEFAULT     3 _RNvCseCSg29WUqSe_7___rustc12___rust_alloc
    10: 0000000000000000     5 FUNC    GLOBAL DEFAULT     5 _RNvCseCSg29WUqSe_7___rustc14___rust_dealloc
    12: 0000000000000000     5 FUNC    GLOBAL DEFAULT     7 _RNvCseCSg29WUqSe_7___rustc14___rust_realloc
    14: 0000000000000000     5 FUNC    GLOBAL DEFAULT     9 _RNvCseCSg29WUqSe_7___rustc19___rust_alloc_zeroed
    16: 0000000000000000     3 FUNC    GLOBAL DEFAULT    11 _RNvCseCSg29WUqSe_7___rustc42___rust_alloc_error_handler_should_panic_v2
    17: 0000000000000000     1 FUNC    GLOBAL DEFAULT    12 _RNvCseCSg29WUqSe_7___rustc35___rust_no_alloc_shim_is_unstable_v2
  3383: 0000000000000000   111 FUNC    GLOBAL DEFAULT     5 _RNvCseCSg29WUqSe_7___rustc10rust_panic
  3387: 0000000000000000    93 FUNC    GLOBAL DEFAULT     7 _RNvCseCSg29WUqSe_7___rustc11___rdl_alloc
  3390: 0000000000000000    10 FUNC    GLOBAL DEFAULT     9 _RNvCseCSg29WUqSe_7___rustc12___rust_abort
  3391: 0000000000000000     6 FUNC    GLOBAL DEFAULT    11 _RNvCseCSg29WUqSe_7___rustc13___rdl_dealloc
  3393: 0000000000000000   167 FUNC    GLOBAL DEFAULT    13 _RNvCseCSg29WUqSe_7___rustc13___rdl_realloc
  3396: 0000000000000000   203 FUNC    GLOBAL DEFAULT    15 _RNvCseCSg29WUqSe_7___rustc17___rust_drop_panic
  3399: 0000000000000000    29 FUNC    GLOBAL DEFAULT    18 _RNvCseCSg29WUqSe_7___rustc17rust_begin_unwind
  3401: 0000000000000000   140 FUNC    GLOBAL DEFAULT    20 _RNvCseCSg29WUqSe_7___rustc18___rdl_alloc_zeroed
  3404: 0000000000000000   203 FUNC    GLOBAL DEFAULT    22 _RNvCseCSg29WUqSe_7___rustc24___rust_foreign_exception
  3405: 0000000000000000    19 FUNC    GLOBAL DEFAULT    25 _RNvCseCSg29WUqSe_7___rustc26___rust_alloc_error_handler
  4410: 0000000000000000  1471 FUNC    GLOBAL DEFAULT   2752 rust_eh_personality
    25: 0000000000000000   161 FUNC    GLOBAL DEFAULT     5 _RNvCseCSg29WUqSe_7___rustc18___rust_start_panic
    32: 0000000000000000    82 FUNC    GLOBAL DEFAULT     8 _RNvCseCSg29WUqSe_7___rustc20___rust_panic_cleanup
   249: 0000000000000000   182 FUNC    GLOBAL DEFAULT     5 _RNvCseCSg29WUqSe_7___rustc25___rdl_alloc_error_handler
     3: 0000000000000000    57 FUNC    GLOBAL DEFAULT     3 _RNvCseCSg29WUqSe_7___rustc17___rust_probestack

After:

     8: 0000000000000000     5 FUNC    GLOBAL DEFAULT     3 _RNvCs4CIB29Id3dw_7___rustc12___rust_alloc
    10: 0000000000000000     5 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc14___rust_dealloc
    12: 0000000000000000     5 FUNC    GLOBAL DEFAULT     7 _RNvCs4CIB29Id3dw_7___rustc14___rust_realloc
    14: 0000000000000000     5 FUNC    GLOBAL DEFAULT     9 _RNvCs4CIB29Id3dw_7___rustc19___rust_alloc_zeroed
    16: 0000000000000000     3 FUNC    GLOBAL DEFAULT    11 _RNvCs4CIB29Id3dw_7___rustc42___rust_alloc_error_handler_should_panic_v2
    17: 0000000000000000     1 FUNC    GLOBAL DEFAULT    12 _RNvCs4CIB29Id3dw_7___rustc35___rust_no_alloc_shim_is_unstable_v2
   422: 0000000000000000    19 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc26___rust_alloc_error_handler
   429: 0000000000000000   308 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc19rust_eh_personality
   349: 0000000000000000    10 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc12___rust_abort
   164: 0000000000000000    93 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc11___rdl_alloc
   167: 0000000000000000    11 FUNC    GLOBAL DEFAULT     7 _RNvCs4CIB29Id3dw_7___rustc13___rdl_dealloc
   169: 0000000000000000   167 FUNC    GLOBAL DEFAULT     9 _RNvCs4CIB29Id3dw_7___rustc13___rdl_realloc
   172: 0000000000000000   140 FUNC    GLOBAL DEFAULT    11 _RNvCs4CIB29Id3dw_7___rustc18___rdl_alloc_zeroed
   688: 0000000000000000   106 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc10rust_panic
   693: 0000000000000000   207 FUNC    GLOBAL DEFAULT     7 _RNvCs4CIB29Id3dw_7___rustc17___rust_drop_panic
   696: 0000000000000000    29 FUNC    GLOBAL DEFAULT    10 _RNvCs4CIB29Id3dw_7___rustc17rust_begin_unwind
   698: 0000000000000000   207 FUNC    GLOBAL DEFAULT    12 _RNvCs4CIB29Id3dw_7___rustc24___rust_foreign_exception
    26: 0000000000000000   161 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc18___rust_start_panic
    33: 0000000000000000    82 FUNC    GLOBAL DEFAULT     8 _RNvCs4CIB29Id3dw_7___rustc20___rust_panic_cleanup
    88: 0000000000000000   182 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc25___rdl_alloc_error_handler
     3: 0000000000000000    57 FUNC    GLOBAL DEFAULT     3 _RNvCs4CIB29Id3dw_7___rustc17___rust_probestack

r? bjorn3

@rustbot
Copy link
Collaborator

rustbot commented Nov 2, 2025

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 2, 2025
@Noratrieb Noratrieb marked this pull request as draft November 2, 2025 20:29
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 2, 2025
@rust-log-analyzer

This comment has been minimized.

@workingjubilee
Copy link
Member

re: LLVM version-detection, do you mean llvm_util::get_version() or?

@bors
Copy link
Collaborator

bors commented Nov 3, 2025

☔ The latest upstream changes (presumably #148420) made this pull request unmergeable. Please resolve the merge conflicts.

rnk pushed a commit to llvm/llvm-project that referenced this pull request Nov 8, 2025
LLVM needs to figure out the type of EH personality for various reasons.
To do this, it currently matches against a hardcoded list of names. In
Rust, we would like to mangle our personality function to better support
linking multiple Rust standard libraries via staticlib. We have
currently mangled all symbols except the personality, which remains
unmangled because of this LLVM hardcoding.

Instead, this now does a suffix match of the personality name, which
will work with the mangling scheme used for these internal symbols (e.g.
`_RNvCseCSg29WUqSe_7___rustc12___rust_alloc`).

Companion Rust PR: rust-lang/rust#148413
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Nov 8, 2025
…efix (#166095)

LLVM needs to figure out the type of EH personality for various reasons.
To do this, it currently matches against a hardcoded list of names. In
Rust, we would like to mangle our personality function to better support
linking multiple Rust standard libraries via staticlib. We have
currently mangled all symbols except the personality, which remains
unmangled because of this LLVM hardcoding.

Instead, this now does a suffix match of the personality name, which
will work with the mangling scheme used for these internal symbols (e.g.
`_RNvCseCSg29WUqSe_7___rustc12___rust_alloc`).

Companion Rust PR: rust-lang/rust#148413
@Noratrieb Noratrieb force-pushed the mangle-rust-eh-personality branch from f98da1c to 9ea88e3 Compare January 31, 2026 15:00
@rust-log-analyzer

This comment has been minimized.

@Noratrieb Noratrieb force-pushed the mangle-rust-eh-personality branch from 9ea88e3 to 15d0368 Compare January 31, 2026 15:31
@rustbot rustbot added A-compiletest Area: The compiletest test runner A-run-make Area: port run-make Makefiles to rmake.rs A-testsuite Area: The testsuite used to check the correctness of rustc T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) labels Jan 31, 2026
@Noratrieb Noratrieb force-pushed the mangle-rust-eh-personality branch 2 times, most recently from 78ccd7b to e9c966b Compare January 31, 2026 15:42
self.lto_supported.store(lto_supported, Ordering::SeqCst);

// FIXME: This needs to mangle the personality, but that requires a tcx.
gccjit::set_global_personality_function_name(b"rust_eh_personality\0");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@antoyo @GuillaumeGomez do you have an idea on how to best fix this? we now need tcx to mangle the symbol, which isn't yet available in the initialization

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we would need to find a place where we have tcx and is only executed once.
If that doesn't exist, I guess it would be safe to put it in some place and store a boolean to only set it once.

Btw, I believe this would make your life simpler if I change gccjit::set_global_personality_function_name() to not require a static string. Do you want me to update libgccjit to copy the string internally?

Copy link
Member Author

@Noratrieb Noratrieb Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can make it take a borrowed string that is then owned internally that would definitely be helpful, yes, since we'll only get a String here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll attempt to fix this in the following days and include it in my current sync PR.
Not sure when I'm going to be able to merge it, though, since crosstool-ng cannot compile the latest GCC.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the set to codegen_crate and just leaked the string. I'm not entirely sure how good this is but it seems to maybe work

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. That's good enough and we can improve this later.

@rust-log-analyzer

This comment has been minimized.

@Noratrieb Noratrieb force-pushed the mangle-rust-eh-personality branch from e9c966b to ee860b6 Compare January 31, 2026 16:38
@rust-log-analyzer

This comment has been minimized.

@Noratrieb Noratrieb force-pushed the mangle-rust-eh-personality branch from ee860b6 to a74a260 Compare January 31, 2026 19:38
@rust-log-analyzer

This comment has been minimized.

@Noratrieb Noratrieb force-pushed the mangle-rust-eh-personality branch from a74a260 to f0f210f Compare January 31, 2026 20:28
@Noratrieb
Copy link
Member Author

let's
@bors try jobs=x86_64-msvc-1,i686-msvc-1,x86_64-mingw-1,test-various,armhf-gnu,aarch64-apple

@rust-bors

This comment has been minimized.

rust-bors bot pushed a commit that referenced this pull request Jan 31, 2026
Mangle personality symbol


try-job: x86_64-msvc-1
try-job: i686-msvc-1
try-job: x86_64-mingw-1
try-job: test-various
try-job: armhf-gnu
try-job: aarch64-apple
@rust-bors
Copy link
Contributor

rust-bors bot commented Feb 1, 2026

☀️ Try build successful (CI)
Build commit: aafcf3b (aafcf3b804155bfda131da64667115bc83b5a87b, parent: 8afe9ff1caa97654c31fb8c259dac9fdf67d6302)

Previously, std-internal symbols (like `__rust_alloc` or `rust_panic`)
were changed to now be mangled via a v0 scheme with the compiler version
hash (`_RNvCs4CIB29Id3dw_7___rustc10rust_panic`) to make it possible to
have multiple staticlibs (as long as they have different version hashes)
in the same program without symbol conflicts. But the personality
function remained unmangled, because LLVM hardcodes that name.

I made a change in LLVM that makes LLVM now check the suffix instead of
an exact match, so we can mangle the personality function with this
scheme.

This removes the last completely unmangled symbol from Rust staticlibs!
(though the mangling is still quite weak, so it's still not as nice as
it would ideally be).

Before, on a trivial staticlib:

```
readelf -s liblib.a | rg GLOBAL | rg -v " UND | HIDDEN " | rg -v ' _ZN'
     8: 0000000000000000     5 FUNC    GLOBAL DEFAULT     3 _RNvCseCSg29WUqSe_7___rustc12___rust_alloc
    10: 0000000000000000     5 FUNC    GLOBAL DEFAULT     5 _RNvCseCSg29WUqSe_7___rustc14___rust_dealloc
    12: 0000000000000000     5 FUNC    GLOBAL DEFAULT     7 _RNvCseCSg29WUqSe_7___rustc14___rust_realloc
    14: 0000000000000000     5 FUNC    GLOBAL DEFAULT     9 _RNvCseCSg29WUqSe_7___rustc19___rust_alloc_zeroed
    16: 0000000000000000     3 FUNC    GLOBAL DEFAULT    11 _RNvCseCSg29WUqSe_7___rustc42___rust_alloc_error_handler_should_panic_v2
    17: 0000000000000000     1 FUNC    GLOBAL DEFAULT    12 _RNvCseCSg29WUqSe_7___rustc35___rust_no_alloc_shim_is_unstable_v2
  3383: 0000000000000000   111 FUNC    GLOBAL DEFAULT     5 _RNvCseCSg29WUqSe_7___rustc10rust_panic
  3387: 0000000000000000    93 FUNC    GLOBAL DEFAULT     7 _RNvCseCSg29WUqSe_7___rustc11___rdl_alloc
  3390: 0000000000000000    10 FUNC    GLOBAL DEFAULT     9 _RNvCseCSg29WUqSe_7___rustc12___rust_abort
  3391: 0000000000000000     6 FUNC    GLOBAL DEFAULT    11 _RNvCseCSg29WUqSe_7___rustc13___rdl_dealloc
  3393: 0000000000000000   167 FUNC    GLOBAL DEFAULT    13 _RNvCseCSg29WUqSe_7___rustc13___rdl_realloc
  3396: 0000000000000000   203 FUNC    GLOBAL DEFAULT    15 _RNvCseCSg29WUqSe_7___rustc17___rust_drop_panic
  3399: 0000000000000000    29 FUNC    GLOBAL DEFAULT    18 _RNvCseCSg29WUqSe_7___rustc17rust_begin_unwind
  3401: 0000000000000000   140 FUNC    GLOBAL DEFAULT    20 _RNvCseCSg29WUqSe_7___rustc18___rdl_alloc_zeroed
  3404: 0000000000000000   203 FUNC    GLOBAL DEFAULT    22 _RNvCseCSg29WUqSe_7___rustc24___rust_foreign_exception
  3405: 0000000000000000    19 FUNC    GLOBAL DEFAULT    25 _RNvCseCSg29WUqSe_7___rustc26___rust_alloc_error_handler
  4410: 0000000000000000  1471 FUNC    GLOBAL DEFAULT   2752 rust_eh_personality
    25: 0000000000000000   161 FUNC    GLOBAL DEFAULT     5 _RNvCseCSg29WUqSe_7___rustc18___rust_start_panic
    32: 0000000000000000    82 FUNC    GLOBAL DEFAULT     8 _RNvCseCSg29WUqSe_7___rustc20___rust_panic_cleanup
   249: 0000000000000000   182 FUNC    GLOBAL DEFAULT     5 _RNvCseCSg29WUqSe_7___rustc25___rdl_alloc_error_handler
     3: 0000000000000000    57 FUNC    GLOBAL DEFAULT     3 _RNvCseCSg29WUqSe_7___rustc17___rust_probestack
```

After:

```
     8: 0000000000000000     5 FUNC    GLOBAL DEFAULT     3 _RNvCs4CIB29Id3dw_7___rustc12___rust_alloc
    10: 0000000000000000     5 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc14___rust_dealloc
    12: 0000000000000000     5 FUNC    GLOBAL DEFAULT     7 _RNvCs4CIB29Id3dw_7___rustc14___rust_realloc
    14: 0000000000000000     5 FUNC    GLOBAL DEFAULT     9 _RNvCs4CIB29Id3dw_7___rustc19___rust_alloc_zeroed
    16: 0000000000000000     3 FUNC    GLOBAL DEFAULT    11 _RNvCs4CIB29Id3dw_7___rustc42___rust_alloc_error_handler_should_panic_v2
    17: 0000000000000000     1 FUNC    GLOBAL DEFAULT    12 _RNvCs4CIB29Id3dw_7___rustc35___rust_no_alloc_shim_is_unstable_v2
   422: 0000000000000000    19 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc26___rust_alloc_error_handler
   429: 0000000000000000   308 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc19rust_eh_personality
   349: 0000000000000000    10 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc12___rust_abort
   164: 0000000000000000    93 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc11___rdl_alloc
   167: 0000000000000000    11 FUNC    GLOBAL DEFAULT     7 _RNvCs4CIB29Id3dw_7___rustc13___rdl_dealloc
   169: 0000000000000000   167 FUNC    GLOBAL DEFAULT     9 _RNvCs4CIB29Id3dw_7___rustc13___rdl_realloc
   172: 0000000000000000   140 FUNC    GLOBAL DEFAULT    11 _RNvCs4CIB29Id3dw_7___rustc18___rdl_alloc_zeroed
   688: 0000000000000000   106 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc10rust_panic
   693: 0000000000000000   207 FUNC    GLOBAL DEFAULT     7 _RNvCs4CIB29Id3dw_7___rustc17___rust_drop_panic
   696: 0000000000000000    29 FUNC    GLOBAL DEFAULT    10 _RNvCs4CIB29Id3dw_7___rustc17rust_begin_unwind
   698: 0000000000000000   207 FUNC    GLOBAL DEFAULT    12 _RNvCs4CIB29Id3dw_7___rustc24___rust_foreign_exception
    26: 0000000000000000   161 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc18___rust_start_panic
    33: 0000000000000000    82 FUNC    GLOBAL DEFAULT     8 _RNvCs4CIB29Id3dw_7___rustc20___rust_panic_cleanup
    88: 0000000000000000   182 FUNC    GLOBAL DEFAULT     5 _RNvCs4CIB29Id3dw_7___rustc25___rdl_alloc_error_handler
     3: 0000000000000000    57 FUNC    GLOBAL DEFAULT     3 _RNvCs4CIB29Id3dw_7___rustc17___rust_probestack
```
@Noratrieb Noratrieb force-pushed the mangle-rust-eh-personality branch from f0f210f to 527ac38 Compare February 1, 2026 10:48
@Noratrieb Noratrieb marked this pull request as ready for review February 1, 2026 11:09
@rustbot
Copy link
Collaborator

rustbot commented Feb 1, 2026

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in src/tools/compiletest

cc @jieyouxu

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

The run-make-support library was changed

cc @jieyouxu

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 1, 2026
.is_some_and(|name| name.ends_with("rust_eh_personality"))
{
unsafe extern "C" {
fn rust_eh_personality() -> !;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would break as there is no longer a rust_eh_personality symbol. This has to be the exact symbol that rust_eh_personality mangles too. Is adding #[lang = "eh_personality"] to this declaration allowed? Also make sure to add the right feature gate in that case.

This code is not tested in the rust CI as it is part of the JIT feature, which is disabled for rustup shipped versions of cg_clif. You could temporarily change Cargo.toml to enable the jit feature by default to test this code.


impl UnwindContext {
pub(crate) fn new(module: &mut dyn Module, pic_eh_frame: bool) -> Self {
pub(crate) fn new(module: &mut dyn Module, tcx: TyCtxt<'_>, pic_eh_frame: bool) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe pass the name of the personality function as argument instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-compiletest Area: The compiletest test runner A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-run-make Area: port run-make Makefiles to rmake.rs A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants