Skip to content

Commit d30d749

Browse files
committed
Add the weak-intrinsics feature
When enabled, the weak-intrinsics feature will cause all intrinsics functions to be marked with weak linkage (i.e. `#[linkage = "weak"]) so that they can be replaced at link time by a stronger symbol. This can be set to use C++ intrinsics from the compiler-rt library, as it will avoid Rust's implementation replacing the compiler-rt implementation as long as the compiler-rt symbols are linked as strong symbols. Typically this requires the compiler-rt library to be explicitly specified in the link command. Addresses rust-lang#525.
1 parent 4677881 commit d30d749

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

Diff for: Cargo.toml

+11
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ rustc-dep-of-std = ['compiler-builtins', 'core']
6565
# are not normally public but are required by the `testcrate`
6666
public-test-deps = []
6767

68+
# Marks all intrinsics functions with weak linkage so that they can be
69+
# replaced at link time by another implementation. This is particularly useful
70+
# for mixed Rust/C++ binaries that want to use the C++ intrinsics, otherwise
71+
# linking against the Rust stdlib will replace those from the compiler-rt
72+
# library.
73+
#
74+
# Unlike the "c" feature, the intrinsics are still provided by the Rust
75+
# implementations and each will be used unless a stronger symbol replaces
76+
# it during linking.
77+
weak-intrinsics = []
78+
6879
[[example]]
6980
name = "intrinsics"
7081
required-features = ["compiler-builtins"]

Diff for: src/macros.rs

+45-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ macro_rules! public_test_dep {
2525
/// platforms need and elsewhere in this library it just looks like normal Rust
2626
/// code.
2727
///
28+
/// When the weak-intrinsics feature is enabled, all intrinsics functions are
29+
/// marked with #[linkage = "weak"] so that they can be replaced by another
30+
/// implementation at link time. This is particularly useful for mixed Rust/C++
31+
/// binaries that want to use the C++ intrinsics, otherwise linking against the
32+
/// Rust stdlib will replace those from the compiler-rt library.
33+
///
2834
/// This macro is structured to be invoked with a bunch of functions that looks
2935
/// like:
3036
///
@@ -218,6 +224,7 @@ macro_rules! intrinsics {
218224
#[cfg(all(any(windows, target_os = "uefi"), target_arch = "x86_64"))]
219225
pub mod $name {
220226
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
227+
#[cfg_attr(feature = "weak-intrinsics", linkage = "weak")]
221228
pub extern $abi fn $name( $($argname: $ty),* )
222229
-> ::macros::win64_128bit_abi_hack::U64x2
223230
{
@@ -258,6 +265,7 @@ macro_rules! intrinsics {
258265
#[cfg(target_arch = "arm")]
259266
pub mod $name {
260267
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
268+
#[cfg_attr(feature = "weak-intrinsics", linkage = "weak")]
261269
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
262270
super::$name($($argname),*)
263271
}
@@ -266,7 +274,7 @@ macro_rules! intrinsics {
266274
#[cfg(target_arch = "arm")]
267275
pub mod $alias {
268276
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
269-
#[cfg_attr(all(not(windows), not(target_vendor="apple")), linkage = "weak")]
277+
#[cfg_attr(any(all(not(windows), not(target_vendor="apple"), feature = "weak-intrinsics")), linkage = "weak")]
270278
pub extern "aapcs" fn $alias( $($argname: $ty),* ) $(-> $ret)? {
271279
super::$name($($argname),*)
272280
}
@@ -283,6 +291,38 @@ macro_rules! intrinsics {
283291
intrinsics!($($rest)*);
284292
);
285293

294+
// Explicit weak linkage gets dropped when weak-intrinsics is on since it
295+
// will be added unconditionally to all intrinsics and would conflict
296+
// otherwise.
297+
(
298+
#[linkage = "weak"]
299+
$(#[$($attr:tt)*])*
300+
pub unsafe extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) $(-> $ret:ty)? {
301+
$($body:tt)*
302+
}
303+
304+
$($rest:tt)*
305+
) => (
306+
#[cfg(feature = "weak-intrinsics")]
307+
intrinsics! {
308+
$(#[$($attr)*])*
309+
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
310+
$($body)*
311+
}
312+
}
313+
314+
#[cfg(not(feature = "weak-intrinsics"))]
315+
intrinsics! {
316+
$(#[$($attr)*])*
317+
#[linkage = "weak"]
318+
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
319+
$($body)*
320+
}
321+
}
322+
323+
intrinsics!($($rest)*);
324+
);
325+
286326
// C mem* functions are only generated when the "mem" feature is enabled.
287327
(
288328
#[mem_builtin]
@@ -302,6 +342,7 @@ macro_rules! intrinsics {
302342
pub mod $name {
303343
$(#[$($attr)*])*
304344
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
345+
#[cfg_attr(feature = "weak-intrinsics", linkage = "weak")]
305346
pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
306347
super::$name($($argname),*)
307348
}
@@ -325,6 +366,7 @@ macro_rules! intrinsics {
325366
#[naked]
326367
$(#[$($attr)*])*
327368
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
369+
#[cfg_attr(feature = "weak-intrinsics", linkage = "weak")]
328370
pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
329371
$($body)*
330372
}
@@ -391,6 +433,7 @@ macro_rules! intrinsics {
391433
pub mod $name {
392434
$(#[$($attr)*])*
393435
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
436+
#[cfg_attr(feature = "weak-intrinsics", linkage = "weak")]
394437
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
395438
super::$name($($argname),*)
396439
}
@@ -416,6 +459,7 @@ macro_rules! intrinsics {
416459
pub mod $name {
417460
$(#[$($attr)*])*
418461
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
462+
#[cfg_attr(feature = "weak-intrinsics", linkage = "weak")]
419463
pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
420464
super::$name($($argname),*)
421465
}

0 commit comments

Comments
 (0)