From 7de57cd4f99fd7a0da0a911f9f9cc79f1d06b909 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 23 Jun 2017 15:16:07 -0700 Subject: [PATCH] Handle aeabi aliasing Objects in compiler-rt may have two symbols, so this makes sure that we don't bring in those objects by accident by defining the aliases ourselves. --- ci/run.sh | 30 +++++++++++---------- src/arm.rs | 58 --------------------------------------- src/float/add.rs | 2 ++ src/float/conv.rs | 14 ++++++++++ src/float/sub.rs | 2 ++ src/int/mul.rs | 1 + src/int/sdiv.rs | 1 + src/int/shift.rs | 3 +++ src/int/udiv.rs | 1 + src/macros.rs | 69 +++++++++++++++++++++++++++++++++++++---------- 10 files changed, 95 insertions(+), 86 deletions(-) diff --git a/ci/run.sh b/ci/run.sh index 3316a43..f61b90f 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -50,19 +50,6 @@ case $1 in ;; esac -# Verify that there are no undefined symbols to `panic` within our implementations -# TODO(#79) fix the undefined references problem for debug-assertions+lto -case $1 in - thumb*) - RUSTFLAGS="-C debug-assertions=no" xargo rustc --features 'c mem' --target $1 --example intrinsics -- -C lto -C link-arg=-nostartfiles - xargo rustc --features 'c mem' --target $1 --example intrinsics --release -- -C lto - ;; - *) - RUSTFLAGS="-C debug-assertions=no" cargo rustc --features 'c mem' --target $1 --example intrinsics -- -C lto - cargo rustc --features 'c mem' --target $1 --example intrinsics --release -- -C lto - ;; -esac - PREFIX=$(echo $1 | sed -e 's/unknown-//')- case $1 in armv7-*) @@ -109,9 +96,24 @@ for rlib in $(echo $path); do set -ex done +rm -f $path + +# Verify that there are no undefined symbols to `panic` within our implementations +# TODO(#79) fix the undefined references problem for debug-assertions+lto +case $1 in + thumb*) + RUSTFLAGS="-C debug-assertions=no" xargo rustc --features 'c mem' --target $1 --example intrinsics -- -C lto -C link-arg=-nostartfiles + xargo rustc --features 'c mem' --target $1 --example intrinsics --release -- -C lto + ;; + *) + RUSTFLAGS="-C debug-assertions=no" cargo rustc --features 'c mem' --target $1 --example intrinsics -- -C lto + cargo rustc --features 'c mem' --target $1 --example intrinsics --release -- -C lto + ;; +esac + # Ensure no references to a panicking function for rlib in $(echo $path); do - set +x + set +ex $PREFIX$NM -u $rlib 2>&1 | grep panicking if test $? = 0; then diff --git a/src/arm.rs b/src/arm.rs index cf960c5..6e1c8f2 100644 --- a/src/arm.rs +++ b/src/arm.rs @@ -60,64 +60,6 @@ pub unsafe fn __aeabi_ldivmod() { intrinsics::unreachable(); } -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_dadd(a: f64, b: f64) -> f64 { - ::float::add::__adddf3(a, b) -} - -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_fadd(a: f32, b: f32) -> f32 { - ::float::add::__addsf3(a, b) -} - -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_dsub(a: f64, b: f64) -> f64 { - ::float::sub::__subdf3(a, b) -} - -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_fsub(a: f32, b: f32) -> f32 { - ::float::sub::__subsf3(a, b) -} - -#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))] -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_idiv(a: i32, b: i32) -> i32 { - ::int::sdiv::__divsi3(a, b) -} - -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_lasr(a: i64, b: u32) -> i64 { - ::int::shift::__ashrdi3(a, b) -} - -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_llsl(a: u64, b: u32) -> u64 { - ::int::shift::__ashldi3(a, b) -} - -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_llsr(a: u64, b: u32) -> u64 { - ::int::shift::__lshrdi3(a, b) -} - -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_lmul(a: u64, b: u64) -> u64 { - ::int::mul::__muldi3(a, b) -} - -#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))] -#[cfg_attr(not(test), no_mangle)] -pub extern "aapcs" fn __aeabi_uidiv(a: u32, b: u32) -> u32 { - ::int::udiv::__udivsi3(a, b) -} - -#[cfg(not(feature = "c"))] -#[cfg_attr(not(test), no_mangle)] -pub extern "C" fn __aeabi_ui2d(a: u32) -> f64 { - ::float::conv::__floatunsidf(a) -} - // TODO: These aeabi_* functions should be defined as aliases #[cfg(not(feature = "mem"))] extern "C" { diff --git a/src/float/add.rs b/src/float/add.rs index 1b1ac3f..696d886 100644 --- a/src/float/add.rs +++ b/src/float/add.rs @@ -181,11 +181,13 @@ macro_rules! add { intrinsics! { #[aapcs_on_arm] + #[arm_aeabi_alias = __aeabi_fadd] pub extern "C" fn __addsf3(a: f32, b: f32) -> f32 { add!(a, b, f32) } #[aapcs_on_arm] + #[arm_aeabi_alias = __aeabi_dadd] pub extern "C" fn __adddf3(a: f64, b: f64) -> f64 { add!(a, b, f64) } diff --git a/src/float/conv.rs b/src/float/conv.rs index ca05c28..8fc2a2a 100644 --- a/src/float/conv.rs +++ b/src/float/conv.rs @@ -70,15 +70,18 @@ macro_rules! int_to_float { } intrinsics! { + #[arm_aeabi_alias = __aeabi_i2f] pub extern "C" fn __floatsisf(i: i32) -> f32 { int_to_float!(i, i32, f32) } + #[arm_aeabi_alias = __aeabi_i2d] pub extern "C" fn __floatsidf(i: i32) -> f64 { int_to_float!(i, i32, f64) } #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] + #[arm_aeabi_alias = __aeabi_l2d] pub extern "C" fn __floatdidf(i: i64) -> f64 { // On x86_64 LLVM will use native instructions for this conversion, we // can just do it directly @@ -99,16 +102,19 @@ intrinsics! { int_to_float!(i, i128, f64) } + #[arm_aeabi_alias = __aeabi_ui2f] pub extern "C" fn __floatunsisf(i: u32) -> f32 { int_to_float!(i, u32, f32) } + #[arm_aeabi_alias = __aeabi_ui2d] pub extern "C" fn __floatunsidf(i: u32) -> f64 { int_to_float!(i, u32, f64) } #[use_c_shim_if(all(any(target_arch = "x86", target_arch = "x86_64"), not(target_env = "msvc")))] + #[arm_aeabi_alias = __aeabi_ul2d] pub extern "C" fn __floatundidf(i: u64) -> f64 { int_to_float!(i, u64, f64) } @@ -182,10 +188,12 @@ macro_rules! float_to_int { } intrinsics! { + #[arm_aeabi_alias = __aeabi_f2iz] pub extern "C" fn __fixsfsi(f: f32) -> i32 { float_to_int!(f, f32, i32) } + #[arm_aeabi_alias = __aeabi_f2lz] pub extern "C" fn __fixsfdi(f: f32) -> i64 { float_to_int!(f, f32, i64) } @@ -195,10 +203,12 @@ intrinsics! { float_to_int!(f, f32, i128) } + #[arm_aeabi_alias = __aeabi_d2iz] pub extern "C" fn __fixdfsi(f: f64) -> i32 { float_to_int!(f, f64, i32) } + #[arm_aeabi_alias = __aeabi_d2lz] pub extern "C" fn __fixdfdi(f: f64) -> i64 { float_to_int!(f, f64, i64) } @@ -208,10 +218,12 @@ intrinsics! { float_to_int!(f, f64, i128) } + #[arm_aeabi_alias = __aeabi_f2uiz] pub extern "C" fn __fixunssfsi(f: f32) -> u32 { float_to_int!(f, f32, u32) } + #[arm_aeabi_alias = __aeabi_f2ulz] pub extern "C" fn __fixunssfdi(f: f32) -> u64 { float_to_int!(f, f32, u64) } @@ -221,10 +233,12 @@ intrinsics! { float_to_int!(f, f32, u128) } + #[arm_aeabi_alias = __aeabi_d2uiz] pub extern "C" fn __fixunsdfsi(f: f64) -> u32 { float_to_int!(f, f64, u32) } + #[arm_aeabi_alias = __aeabi_d2ulz] pub extern "C" fn __fixunsdfdi(f: f64) -> u64 { float_to_int!(f, f64, u64) } diff --git a/src/float/sub.rs b/src/float/sub.rs index a82a943..4fa436d 100644 --- a/src/float/sub.rs +++ b/src/float/sub.rs @@ -1,10 +1,12 @@ use float::Float; intrinsics! { + #[arm_aeabi_alias = __aeabi_fsub] pub extern "C" fn __subsf3(a: f32, b: f32) -> f32 { a + f32::from_repr(b.repr() ^ f32::sign_mask()) } + #[arm_aeabi_alias = __aeabi_dsub] pub extern "C" fn __subdf3(a: f64, b: f64) -> f64 { a + f64::from_repr(b.repr() ^ f64::sign_mask()) } diff --git a/src/int/mul.rs b/src/int/mul.rs index 9241ee6..d61a6b4 100644 --- a/src/int/mul.rs +++ b/src/int/mul.rs @@ -72,6 +72,7 @@ impl Mulo for i128 {} intrinsics! { #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] + #[arm_aeabi_alias = __aeabi_lmul] pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 { a.mul(b) } diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index 8d85630..6ce7ffd 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -60,6 +60,7 @@ impl Divmod for i64 {} intrinsics! { #[use_c_shim_if(all(target_arch = "arm", not(target_os = "ios"), not(thumbv6m)))] + #[arm_aeabi_alias = __aeabi_idiv] pub extern "C" fn __divsi3(a: i32, b: i32) -> i32 { a.div(b) } diff --git a/src/int/shift.rs b/src/int/shift.rs index b0103ce..a9b6c05 100644 --- a/src/int/shift.rs +++ b/src/int/shift.rs @@ -66,6 +66,7 @@ impl Lshr for u128 {} intrinsics! { #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] + #[arm_aeabi_alias = __aeabi_llsl] pub extern "C" fn __ashldi3(a: u64, b: u32) -> u64 { a.ashl(b) } @@ -75,6 +76,7 @@ intrinsics! { } #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] + #[arm_aeabi_alias = __aeabi_lasr] pub extern "C" fn __ashrdi3(a: i64, b: u32) -> i64 { a.ashr(b) } @@ -84,6 +86,7 @@ intrinsics! { } #[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] + #[arm_aeabi_alias = __aeabi_llsr] pub extern "C" fn __lshrdi3(a: u64, b: u32) -> u64 { a.lshr(b) } diff --git a/src/int/udiv.rs b/src/int/udiv.rs index 90ac729..27baff9 100644 --- a/src/int/udiv.rs +++ b/src/int/udiv.rs @@ -155,6 +155,7 @@ intrinsics! { #[use_c_shim_if(all(target_arch = "arm", not(target_os = "ios"), not(thumbv6m)))] + #[arm_aeabi_alias = __aeabi_uidiv] /// Returns `n / d` pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 { // Special cases diff --git a/src/macros.rs b/src/macros.rs index 740eae2..2e65e96 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -7,7 +7,7 @@ macro_rules! intrinsics { // intrinsic. ( #[use_c_shim_if($($cfg_clause:tt)*)] - $(#[$attr:meta])* + $(#[$($attr:tt)*])* pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { $($body:tt)* } @@ -16,7 +16,6 @@ macro_rules! intrinsics { ) => ( #[cfg(all(feature = "c", $($cfg_clause)*))] - $(#[$attr])* pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { extern $abi { fn $name($($argname: $ty),*) -> $ret; @@ -28,7 +27,7 @@ macro_rules! intrinsics { #[cfg(not(all(feature = "c", $($cfg_clause)*)))] intrinsics! { - $(#[$attr])* + $(#[$($attr)*])* pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { $($body)* } @@ -42,7 +41,7 @@ macro_rules! intrinsics { // ARM and `"C"` elsewhere. ( #[aapcs_on_arm] - $(#[$attr:meta])* + $(#[$($attr:tt)*])* pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { $($body:tt)* } @@ -51,7 +50,7 @@ macro_rules! intrinsics { ) => ( #[cfg(target_arch = "arm")] intrinsics! { - $(#[$attr])* + $(#[$($attr)*])* pub extern "aapcs" fn $name( $($argname: $ty),* ) -> $ret { $($body)* } @@ -59,7 +58,7 @@ macro_rules! intrinsics { #[cfg(not(target_arch = "arm"))] intrinsics! { - $(#[$attr])* + $(#[$($attr)*])* pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { $($body)* } @@ -72,7 +71,7 @@ macro_rules! intrinsics { // win64 for some methods. ( #[unadjusted_on_win64] - $(#[$attr:meta])* + $(#[$($attr:tt)*])* pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { $($body:tt)* } @@ -81,7 +80,7 @@ macro_rules! intrinsics { ) => ( #[cfg(all(windows, target_pointer_width = "64"))] intrinsics! { - $(#[$attr])* + $(#[$($attr)*])* pub extern "unadjusted" fn $name( $($argname: $ty),* ) -> $ret { $($body)* } @@ -89,7 +88,7 @@ macro_rules! intrinsics { #[cfg(not(all(windows, target_pointer_width = "64")))] intrinsics! { - $(#[$attr])* + $(#[$($attr)*])* pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { $($body)* } @@ -102,7 +101,7 @@ macro_rules! intrinsics { // bit calling convention correct. ( #[win64_128bit_abi_hack] - $(#[$attr:meta])* + $(#[$($attr:tt)*])* pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { $($body:tt)* } @@ -110,7 +109,7 @@ macro_rules! intrinsics { $($rest:tt)* ) => ( #[cfg(all(windows, target_pointer_width = "64"))] - $(#[$attr])* + $(#[$($attr)*])* pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { $($body)* } @@ -130,7 +129,49 @@ macro_rules! intrinsics { #[cfg(not(all(windows, target_pointer_width = "64")))] intrinsics! { - $(#[$attr])* + $(#[$($attr)*])* + pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { + $($body)* + } + } + + intrinsics!($($rest)*); + ); + + // A bunch of intrinsics on ARM are aliased in the standard compiler-rt + // build under `__aeabi_*` aliases, and LLVM will call these instead of the + // original function. Handle that here + ( + #[arm_aeabi_alias = $alias:ident] + $(#[$($attr:tt)*])* + pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { + $($body:tt)* + } + + $($rest:tt)* + ) => ( + #[cfg(target_arch = "arm")] + $(#[$($attr)*])* + pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { + $($body)* + } + + #[cfg(target_arch = "arm")] + pub mod $name { + intrinsics! { + pub extern "aapcs" fn $alias( $($argname: $ty),* ) -> $ret { + super::$name($($argname),*) + } + + pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { + super::$name($($argname),*) + } + } + } + + #[cfg(not(target_arch = "arm"))] + intrinsics! { + $(#[$($attr)*])* pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { $($body)* } @@ -140,14 +181,14 @@ macro_rules! intrinsics { ); ( - $(#[$attr:meta])* + $(#[$($attr:tt)*])* pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { $($body:tt)* } $($rest:tt)* ) => ( - $(#[$attr])* + $(#[$($attr)*])* #[cfg_attr(not(test), no_mangle)] pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { $($body)*