Merge pull request #598 from Amjad50/remove_weak-intrinsics
Apply `weak` attributes to all intrinsics
This commit is contained in:
commit
55f590fe3b
5 changed files with 38 additions and 139 deletions
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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),*)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue