How rustc manage to link both panic-abort and panic-unwind on the same binary?

This question is not really embedded, but is closer to embedded than general rust usage.

I created a trivial hello world application and built it with the following command line for this tier 3 target:

RUSTFLAGS="--emit=asm -g -C passes=loweratomic" cargo +nightly build -Zbuild-std=std,panic_abort -Zbuild-std-features=compiler-builtins-mem --target riscv32im-risc0-zkvm-elf --verbose

It all goes fine, but when I look into the assembly files emitted, I see that the symbol __rust_panic_cleanup is duplicated in both libpanic_abort and libpanic_unwind. At first I thought that was a quirk of cargo, and at most one was supplied to the final rustc invocation. But no, if I inspect the --verbose output, I can see that both are provided:

[...] --extern 'noprelude:panic_abort=[...]/target/riscv32im-risc0-zkvm-elf/debug/deps/libpanic_abort-be67a198f4b50054.rlib' --extern 'noprelude:panic_unwind=[...]/target/riscv32im-risc0-zkvm-elf/debug/deps/libpanic_unwind-edaa0a86e5842749.rlib' [...]

I am working on a context of a zkVM similar to risc0, and we do have to perform our own liking, so I would like to know how the repeated symbol is handled by rustc/lld, because our linker currently does not support repeated symbols and I will probably have to fix it.

Even though libstd declares a dependency on both the panic_abort and panic_unwind crates, rustc has special logic to only link one of the two depending on if code is compiled with -Cpanic=abort or -Cpanic=unwind.

I manually filtered out panic_unwind, but then I got this other, very similar, problem: when I tried to link with a crate defining the #[panic_handler], the symbol rust_begin_unwind is duplicated both in my crate and std. And I guess if our code didn't stop at the first error, we would also get an error due to #[global_allocator] being defined, rustc seems full of special logic when it comes to linking against std.

So, is there a not very complicated way to get what symbols from where are actually being delivered to linker, after all the special logic?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.