diff --git a/Cargo.toml b/Cargo.toml index 96e85d7b..c8f164c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,17 +70,6 @@ rustc-dep-of-std = ['compiler-builtins', 'core'] # are not normally public but are required by the `testcrate` public-test-deps = [] -# Marks all intrinsics functions with weak linkage so that they can be -# replaced at link time by another implementation. This is particularly useful -# for mixed Rust/C++ binaries that want to use the C++ intrinsics, otherwise -# linking against the Rust stdlib will replace those from the compiler-rt -# library. -# -# Unlike the "c" feature, the intrinsics are still provided by the Rust -# implementations and each will be used unless a stronger symbol replaces -# it during linking. -weak-intrinsics = [] - [[example]] name = "intrinsics" required-features = ["compiler-builtins"] diff --git a/src/arm.rs b/src/arm.rs index cc67642e..dcae22b7 100644 --- a/src/arm.rs +++ b/src/arm.rs @@ -20,7 +20,6 @@ macro_rules! bl { intrinsics! { // NOTE This function and the ones below are implemented using assembly because they are using a // custom calling convention which can't be implemented using a normal Rust function. - #[cfg_attr(all(not(windows), not(target_vendor="apple")), weak)] #[naked] #[cfg(not(target_env = "msvc"))] pub unsafe extern "C" fn __aeabi_uidivmod() { @@ -36,7 +35,6 @@ intrinsics! { ); } - #[cfg_attr(all(not(windows), not(target_vendor="apple")), weak)] #[naked] pub unsafe extern "C" fn __aeabi_uldivmod() { core::arch::asm!( @@ -53,7 +51,6 @@ intrinsics! { ); } - #[cfg_attr(all(not(windows), not(target_vendor="apple")), weak)] #[naked] pub unsafe extern "C" fn __aeabi_idivmod() { core::arch::asm!( @@ -67,7 +64,6 @@ intrinsics! { ); } - #[cfg_attr(all(not(windows), not(target_vendor="apple")), weak)] #[naked] pub unsafe extern "C" fn __aeabi_ldivmod() { core::arch::asm!( @@ -84,17 +80,13 @@ intrinsics! { ); } - // The following functions use weak linkage to allow users to override - // with custom implementation. // FIXME: The `*4` and `*8` variants should be defined as aliases. - #[weak] #[cfg(not(target_os = "ios"))] pub unsafe extern "aapcs" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize) { crate::mem::memcpy(dest, src, n); } - #[weak] #[cfg(not(target_os = "ios"))] pub unsafe extern "aapcs" fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize) { // We are guaranteed 4-alignment, so accessing at u32 is okay. @@ -112,38 +104,32 @@ intrinsics! { __aeabi_memcpy(dest as *mut u8, src as *const u8, n); } - #[weak] #[cfg(not(target_os = "ios"))] pub unsafe extern "aapcs" fn __aeabi_memcpy8(dest: *mut u8, src: *const u8, n: usize) { __aeabi_memcpy4(dest, src, n); } - #[weak] #[cfg(not(target_os = "ios"))] pub unsafe extern "aapcs" fn __aeabi_memmove(dest: *mut u8, src: *const u8, n: usize) { crate::mem::memmove(dest, src, n); } - #[weak] #[cfg(not(any(target_os = "ios", target_env = "msvc")))] pub unsafe extern "aapcs" fn __aeabi_memmove4(dest: *mut u8, src: *const u8, n: usize) { __aeabi_memmove(dest, src, n); } - #[weak] #[cfg(not(any(target_os = "ios", target_env = "msvc")))] pub unsafe extern "aapcs" fn __aeabi_memmove8(dest: *mut u8, src: *const u8, n: usize) { __aeabi_memmove(dest, src, n); } - #[weak] #[cfg(not(target_os = "ios"))] pub unsafe extern "aapcs" fn __aeabi_memset(dest: *mut u8, n: usize, c: i32) { // Note the different argument order crate::mem::memset(dest, c, n); } - #[weak] #[cfg(not(target_os = "ios"))] pub unsafe extern "aapcs" fn __aeabi_memset4(dest: *mut u8, n: usize, c: i32) { let mut dest = dest as *mut u32; @@ -161,25 +147,21 @@ intrinsics! { __aeabi_memset(dest as *mut u8, n, byte as i32); } - #[weak] #[cfg(not(target_os = "ios"))] pub unsafe extern "aapcs" fn __aeabi_memset8(dest: *mut u8, n: usize, c: i32) { __aeabi_memset4(dest, n, c); } - #[weak] #[cfg(not(target_os = "ios"))] pub unsafe extern "aapcs" fn __aeabi_memclr(dest: *mut u8, n: usize) { __aeabi_memset(dest, n, 0); } - #[weak] #[cfg(not(any(target_os = "ios", target_env = "msvc")))] pub unsafe extern "aapcs" fn __aeabi_memclr4(dest: *mut u8, n: usize) { __aeabi_memset4(dest, n, 0); } - #[weak] #[cfg(not(any(target_os = "ios", target_env = "msvc")))] pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) { __aeabi_memset4(dest, n, 0); diff --git a/src/macros.rs b/src/macros.rs index 2aa9a742..f762ef4d 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -25,11 +25,12 @@ macro_rules! public_test_dep { /// platforms need and elsewhere in this library it just looks like normal Rust /// code. /// -/// When the weak-intrinsics feature is enabled, all intrinsics functions are -/// marked with #[linkage = "weak"] so that they can be replaced by another -/// implementation at link time. This is particularly useful for mixed Rust/C++ -/// binaries that want to use the C++ intrinsics, otherwise linking against the -/// Rust stdlib will replace those from the compiler-rt library. +/// All intrinsics functions are marked with #[linkage = "weak"] when +/// `not(windows) and not(target_vendor = "apple")`. +/// `weak` linkage attribute is used so that these functions can be replaced +/// by another implementation at link time. This is particularly useful for mixed +/// Rust/C++ binaries that want to use the C++ intrinsics, otherwise linking against +/// the Rust stdlib will replace those from the compiler-rt library. /// /// This macro is structured to be invoked with a bunch of functions that looks /// like: @@ -53,10 +54,6 @@ macro_rules! public_test_dep { /// /// A quick overview of attributes supported right now are: /// -/// * `weak` - indicates that the function should always be given weak linkage. -/// This attribute must come before other attributes, as the other attributes -/// will generate the final output function and need to have `weak` modify -/// them. /// * `maybe_use_optimized_c_shim` - indicates that the Rust implementation is /// ignored if an optimized C version was compiled. /// * `aapcs_on_arm` - forces the ABI of the function to be `"aapcs"` on ARM and @@ -128,67 +125,6 @@ macro_rules! intrinsics { intrinsics!($($rest)*); ); - // Explicit weak linkage gets dropped when weak-intrinsics is on since it - // will be added unconditionally to all intrinsics and would conflict - // otherwise. - ( - #[weak] - $(#[$($attr:tt)*])* - pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) $(-> $ret:ty)? { - $($body:tt)* - } - - $($rest:tt)* - ) => ( - #[cfg(feature = "weak-intrinsics")] - intrinsics! { - $(#[$($attr)*])* - pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { - $($body)* - } - } - - #[cfg(not(feature = "weak-intrinsics"))] - intrinsics! { - $(#[$($attr)*])* - #[linkage = "weak"] - pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { - $($body)* - } - } - - intrinsics!($($rest)*); - ); - // Same as above but for unsafe. - ( - #[weak] - $(#[$($attr:tt)*])* - pub unsafe extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) $(-> $ret:ty)? { - $($body:tt)* - } - - $($rest:tt)* - ) => ( - #[cfg(feature = "weak-intrinsics")] - intrinsics! { - $(#[$($attr)*])* - pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { - $($body)* - } - } - - #[cfg(not(feature = "weak-intrinsics"))] - intrinsics! { - $(#[$($attr)*])* - #[linkage = "weak"] - pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { - $($body)* - } - } - - intrinsics!($($rest)*); - ); - // Right now there's a bunch of architecture-optimized intrinsics in the // stock compiler-rt implementation. Not all of these have been ported over // to Rust yet so when the `c` feature of this crate is enabled we fall back @@ -211,7 +147,6 @@ macro_rules! intrinsics { $($rest:tt)* ) => ( #[cfg($name = "optimized-c")] - #[cfg_attr(feature = "weak-intrinsics", linkage = "weak")] pub $(unsafe $($empty)? )? extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { extern $abi { fn $name($($argname: $ty),*) $(-> $ret)?; @@ -311,16 +246,15 @@ macro_rules! intrinsics { ) => ( #[cfg(all(any(windows, target_os = "uefi"), target_arch = "x86_64"))] $(#[$($attr)*])* - #[cfg_attr(feature = "weak-intrinsics", linkage = "weak")] pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { $($body)* } - #[cfg(all(any(windows, target_os = "uefi"), target_arch = "x86_64"))] - pub mod $name { - #[cfg_attr(not(feature = "mangled-names"), no_mangle)] - #[cfg_attr(feature = "weak-intrinsics", linkage = "weak")] - pub extern $abi fn $name( $($argname: $ty),* ) + #[cfg(all(any(windows, target_os = "uefi"), target_arch = "x86_64", not(feature = "mangled-names")))] + mod $name { + #[no_mangle] + #[cfg_attr(all(not(windows), not(target_vendor = "apple")), linkage = "weak")] + extern $abi fn $name( $($argname: $ty),* ) -> $crate::macros::win64_128bit_abi_hack::U64x2 { let e: $($ret)? = super::$name($($argname),*); @@ -357,20 +291,20 @@ macro_rules! intrinsics { $($body)* } - #[cfg(target_arch = "arm")] - pub mod $name { - #[cfg_attr(not(feature = "mangled-names"), no_mangle)] - #[cfg_attr(feature = "weak-intrinsics", linkage = "weak")] - pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { + #[cfg(all(target_arch = "arm", not(feature = "mangled-names")))] + mod $name { + #[no_mangle] + #[cfg_attr(all(not(windows), not(target_vendor = "apple")), linkage = "weak")] + extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { super::$name($($argname),*) } } - #[cfg(target_arch = "arm")] - pub mod $alias { - #[cfg_attr(not(feature = "mangled-names"), no_mangle)] - #[cfg_attr(any(all(not(windows), not(target_vendor="apple")), feature = "weak-intrinsics"), linkage = "weak")] - pub extern "aapcs" fn $alias( $($argname: $ty),* ) $(-> $ret)? { + #[cfg(all(target_arch = "arm", not(feature = "mangled-names")))] + mod $alias { + #[no_mangle] + #[cfg_attr(all(not(windows), not(target_vendor="apple")), linkage = "weak")] + extern "aapcs" fn $alias( $($argname: $ty),* ) $(-> $ret)? { super::$name($($argname),*) } } @@ -401,12 +335,12 @@ macro_rules! intrinsics { $($body)* } - #[cfg(feature = "mem")] - pub mod $name { + #[cfg(all(feature = "mem", not(feature = "mangled-names")))] + mod $name { $(#[$($attr)*])* - #[cfg_attr(not(feature = "mangled-names"), no_mangle)] - #[cfg_attr(feature = "weak-intrinsics", linkage = "weak")] - pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { + #[no_mangle] + #[cfg_attr(all(not(windows), not(target_vendor = "apple")), linkage = "weak")] + unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { super::$name($($argname),*) } } @@ -425,11 +359,12 @@ macro_rules! intrinsics { $($rest:tt)* ) => ( + // `#[naked]` definitions are referenced by other places, so we can't use `cfg` like the others pub mod $name { #[naked] $(#[$($attr)*])* #[cfg_attr(not(feature = "mangled-names"), no_mangle)] - #[cfg_attr(feature = "weak-intrinsics", linkage = "weak")] + #[cfg_attr(all(not(windows), not(target_vendor = "apple")), linkage = "weak")] pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { $($body)* } @@ -492,11 +427,12 @@ macro_rules! intrinsics { $($body)* } - pub mod $name { + #[cfg(not(feature = "mangled-names"))] + mod $name { $(#[$($attr)*])* - #[cfg_attr(not(feature = "mangled-names"), no_mangle)] - #[cfg_attr(feature = "weak-intrinsics", linkage = "weak")] - pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { + #[no_mangle] + #[cfg_attr(all(not(windows), not(target_vendor = "apple")), linkage = "weak")] + extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { super::$name($($argname),*) } } @@ -518,11 +454,12 @@ macro_rules! intrinsics { $($body)* } - pub mod $name { + #[cfg(not(feature = "mangled-names"))] + mod $name { $(#[$($attr)*])* - #[cfg_attr(not(feature = "mangled-names"), no_mangle)] - #[cfg_attr(feature = "weak-intrinsics", linkage = "weak")] - pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { + #[no_mangle] + #[cfg_attr(all(not(windows), not(target_vendor = "apple")), linkage = "weak")] + unsafe fn $name( $($argname: $ty),* ) $(-> $ret)? { super::$name($($argname),*) } } diff --git a/src/math.rs b/src/math.rs index e47b834e..7d4d1787 100644 --- a/src/math.rs +++ b/src/math.rs @@ -9,7 +9,6 @@ macro_rules! no_mangle { ($(fn $fun:ident($($iid:ident : $ity:ty),+) -> $oty:ty;)+) => { intrinsics! { $( - #[cfg_attr(all(not(windows), not(target_vendor = "apple")), weak)] pub extern "C" fn $fun($($iid: $ity),+) -> $oty { self::libm::$fun($($iid),+) } @@ -94,14 +93,12 @@ no_mangle! { } intrinsics! { - #[cfg_attr(all(not(windows), not(target_vendor = "apple")), weak)] pub extern "C" fn lgamma_r(x: f64, s: &mut i32) -> f64 { let r = self::libm::lgamma_r(x); *s = r.1; r.0 } - #[cfg_attr(all(not(windows), not(target_vendor = "apple")), weak)] pub extern "C" fn lgammaf_r(x: f32, s: &mut i32) -> f32 { let r = self::libm::lgammaf_r(x); *s = r.1; diff --git a/src/mem/mod.rs b/src/mem/mod.rs index ccf19177..d0ff5015 100644 --- a/src/mem/mod.rs +++ b/src/mem/mod.rs @@ -20,14 +20,12 @@ use core::ops::{BitOr, Shl}; mod impls; intrinsics! { - #[cfg_attr(not(all(target_os = "windows", target_env = "gnu")), weak)] #[mem_builtin] pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { impls::copy_forward(dest, src, n); dest } - #[cfg_attr(not(all(target_os = "windows", target_env = "gnu")), weak)] #[mem_builtin] pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { let delta = (dest as usize).wrapping_sub(src as usize); @@ -41,26 +39,22 @@ intrinsics! { dest } - #[cfg_attr(not(all(target_os = "windows", target_env = "gnu")), weak)] #[mem_builtin] pub unsafe extern "C" fn memset(s: *mut u8, c: crate::mem::c_int, n: usize) -> *mut u8 { impls::set_bytes(s, c as u8, n); s } - #[cfg_attr(not(all(target_os = "windows", target_env = "gnu")), weak)] #[mem_builtin] pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 { impls::compare_bytes(s1, s2, n) } - #[cfg_attr(not(all(target_os = "windows", target_env = "gnu")), weak)] #[mem_builtin] pub unsafe extern "C" fn bcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 { memcmp(s1, s2, n) } - #[cfg_attr(not(all(target_os = "windows", target_env = "gnu")), weak)] #[mem_builtin] pub unsafe extern "C" fn strlen(s: *const core::ffi::c_char) -> usize { impls::c_string_length(s)