-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
Summary
You should revert commit 07c7e5f or add an officially supported way of controling ELF linkage.
Reproduce
In Rust 1.87 and before on GNU/Linux, this code:
#![feature(rustc_attrs)]
#[rustc_std_internal_symbol]
#[no_mangle]
pub extern "C" fn blah(i: u32) -> u32 {
i+1
}
produced an object with the blah
symbol marked with internal linkage (t
in nm output)
This is required when linking a Rust shared library with C dependencies which call back to the Rust code, when the blah
function is an internal
glue function that should not be exported from the library.
What this issue is not applicable to:
- linking most executables as opposed to DLLs (executables have exports removed by default during linking)
- linking Rust code in a staticlib into a C library (we can use the likes of
-Wl,--exclude-libs
to hide any offending exports) - linking anything in pure Rust (there are no FFI requirements, any instances of
#[no_mangle]
can be removed from code)
Omitting the #[rustc_std_internal_symbol]
produces a correctly-named symbol, but with incorrect external linkage (T
in nm output).
Such symbol can be called from outside the DLL, which we don't want to.
In C++, mangling (controlled by extern "C"
) and linkage (controlled by the visibility
attribute) are completely orthogonal concepts. One should not control the other.
The exact analog to #[rustc_std_internal_symbol]
in C/C++ is __attribute__((visibility("hidden")))
and we are trying to reproduce its effect on the ELF object.
Version it worked on
1.87.0
Version with regression
1.88.0
Error output
error: `#[no_mangle]` cannot be used on internal language items
--> <source>:5:1
|
5 | #[no_mangle]
| ^^^^^^^^^^^^
6 | pub extern "C" fn blah(i: u32) -> u32 {
| ------------------------------------- should be the internal language item
|
= note: Rustc requires this item to have a specific mangled name.