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.
This commit is contained in:
Alex Crichton 2017-06-23 15:16:07 -07:00
parent a839d53a02
commit 7de57cd4f9
10 changed files with 95 additions and 86 deletions

View File

@ -50,19 +50,6 @@ case $1 in
;; ;;
esac 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-//')- PREFIX=$(echo $1 | sed -e 's/unknown-//')-
case $1 in case $1 in
armv7-*) armv7-*)
@ -109,9 +96,24 @@ for rlib in $(echo $path); do
set -ex set -ex
done 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 # Ensure no references to a panicking function
for rlib in $(echo $path); do for rlib in $(echo $path); do
set +x set +ex
$PREFIX$NM -u $rlib 2>&1 | grep panicking $PREFIX$NM -u $rlib 2>&1 | grep panicking
if test $? = 0; then if test $? = 0; then

View File

@ -60,64 +60,6 @@ pub unsafe fn __aeabi_ldivmod() {
intrinsics::unreachable(); 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 // TODO: These aeabi_* functions should be defined as aliases
#[cfg(not(feature = "mem"))] #[cfg(not(feature = "mem"))]
extern "C" { extern "C" {

View File

@ -181,11 +181,13 @@ macro_rules! add {
intrinsics! { intrinsics! {
#[aapcs_on_arm] #[aapcs_on_arm]
#[arm_aeabi_alias = __aeabi_fadd]
pub extern "C" fn __addsf3(a: f32, b: f32) -> f32 { pub extern "C" fn __addsf3(a: f32, b: f32) -> f32 {
add!(a, b, f32) add!(a, b, f32)
} }
#[aapcs_on_arm] #[aapcs_on_arm]
#[arm_aeabi_alias = __aeabi_dadd]
pub extern "C" fn __adddf3(a: f64, b: f64) -> f64 { pub extern "C" fn __adddf3(a: f64, b: f64) -> f64 {
add!(a, b, f64) add!(a, b, f64)
} }

View File

@ -70,15 +70,18 @@ macro_rules! int_to_float {
} }
intrinsics! { intrinsics! {
#[arm_aeabi_alias = __aeabi_i2f]
pub extern "C" fn __floatsisf(i: i32) -> f32 { pub extern "C" fn __floatsisf(i: i32) -> f32 {
int_to_float!(i, i32, f32) int_to_float!(i, i32, f32)
} }
#[arm_aeabi_alias = __aeabi_i2d]
pub extern "C" fn __floatsidf(i: i32) -> f64 { pub extern "C" fn __floatsidf(i: i32) -> f64 {
int_to_float!(i, i32, f64) int_to_float!(i, i32, f64)
} }
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] #[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 { pub extern "C" fn __floatdidf(i: i64) -> f64 {
// On x86_64 LLVM will use native instructions for this conversion, we // On x86_64 LLVM will use native instructions for this conversion, we
// can just do it directly // can just do it directly
@ -99,16 +102,19 @@ intrinsics! {
int_to_float!(i, i128, f64) int_to_float!(i, i128, f64)
} }
#[arm_aeabi_alias = __aeabi_ui2f]
pub extern "C" fn __floatunsisf(i: u32) -> f32 { pub extern "C" fn __floatunsisf(i: u32) -> f32 {
int_to_float!(i, u32, f32) int_to_float!(i, u32, f32)
} }
#[arm_aeabi_alias = __aeabi_ui2d]
pub extern "C" fn __floatunsidf(i: u32) -> f64 { pub extern "C" fn __floatunsidf(i: u32) -> f64 {
int_to_float!(i, u32, f64) int_to_float!(i, u32, f64)
} }
#[use_c_shim_if(all(any(target_arch = "x86", target_arch = "x86_64"), #[use_c_shim_if(all(any(target_arch = "x86", target_arch = "x86_64"),
not(target_env = "msvc")))] not(target_env = "msvc")))]
#[arm_aeabi_alias = __aeabi_ul2d]
pub extern "C" fn __floatundidf(i: u64) -> f64 { pub extern "C" fn __floatundidf(i: u64) -> f64 {
int_to_float!(i, u64, f64) int_to_float!(i, u64, f64)
} }
@ -182,10 +188,12 @@ macro_rules! float_to_int {
} }
intrinsics! { intrinsics! {
#[arm_aeabi_alias = __aeabi_f2iz]
pub extern "C" fn __fixsfsi(f: f32) -> i32 { pub extern "C" fn __fixsfsi(f: f32) -> i32 {
float_to_int!(f, f32, i32) float_to_int!(f, f32, i32)
} }
#[arm_aeabi_alias = __aeabi_f2lz]
pub extern "C" fn __fixsfdi(f: f32) -> i64 { pub extern "C" fn __fixsfdi(f: f32) -> i64 {
float_to_int!(f, f32, i64) float_to_int!(f, f32, i64)
} }
@ -195,10 +203,12 @@ intrinsics! {
float_to_int!(f, f32, i128) float_to_int!(f, f32, i128)
} }
#[arm_aeabi_alias = __aeabi_d2iz]
pub extern "C" fn __fixdfsi(f: f64) -> i32 { pub extern "C" fn __fixdfsi(f: f64) -> i32 {
float_to_int!(f, f64, i32) float_to_int!(f, f64, i32)
} }
#[arm_aeabi_alias = __aeabi_d2lz]
pub extern "C" fn __fixdfdi(f: f64) -> i64 { pub extern "C" fn __fixdfdi(f: f64) -> i64 {
float_to_int!(f, f64, i64) float_to_int!(f, f64, i64)
} }
@ -208,10 +218,12 @@ intrinsics! {
float_to_int!(f, f64, i128) float_to_int!(f, f64, i128)
} }
#[arm_aeabi_alias = __aeabi_f2uiz]
pub extern "C" fn __fixunssfsi(f: f32) -> u32 { pub extern "C" fn __fixunssfsi(f: f32) -> u32 {
float_to_int!(f, f32, u32) float_to_int!(f, f32, u32)
} }
#[arm_aeabi_alias = __aeabi_f2ulz]
pub extern "C" fn __fixunssfdi(f: f32) -> u64 { pub extern "C" fn __fixunssfdi(f: f32) -> u64 {
float_to_int!(f, f32, u64) float_to_int!(f, f32, u64)
} }
@ -221,10 +233,12 @@ intrinsics! {
float_to_int!(f, f32, u128) float_to_int!(f, f32, u128)
} }
#[arm_aeabi_alias = __aeabi_d2uiz]
pub extern "C" fn __fixunsdfsi(f: f64) -> u32 { pub extern "C" fn __fixunsdfsi(f: f64) -> u32 {
float_to_int!(f, f64, u32) float_to_int!(f, f64, u32)
} }
#[arm_aeabi_alias = __aeabi_d2ulz]
pub extern "C" fn __fixunsdfdi(f: f64) -> u64 { pub extern "C" fn __fixunsdfdi(f: f64) -> u64 {
float_to_int!(f, f64, u64) float_to_int!(f, f64, u64)
} }

View File

@ -1,10 +1,12 @@
use float::Float; use float::Float;
intrinsics! { intrinsics! {
#[arm_aeabi_alias = __aeabi_fsub]
pub extern "C" fn __subsf3(a: f32, b: f32) -> f32 { pub extern "C" fn __subsf3(a: f32, b: f32) -> f32 {
a + f32::from_repr(b.repr() ^ f32::sign_mask()) a + f32::from_repr(b.repr() ^ f32::sign_mask())
} }
#[arm_aeabi_alias = __aeabi_dsub]
pub extern "C" fn __subdf3(a: f64, b: f64) -> f64 { pub extern "C" fn __subdf3(a: f64, b: f64) -> f64 {
a + f64::from_repr(b.repr() ^ f64::sign_mask()) a + f64::from_repr(b.repr() ^ f64::sign_mask())
} }

View File

@ -72,6 +72,7 @@ impl Mulo for i128 {}
intrinsics! { intrinsics! {
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] #[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 { pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 {
a.mul(b) a.mul(b)
} }

View File

@ -60,6 +60,7 @@ impl Divmod for i64 {}
intrinsics! { intrinsics! {
#[use_c_shim_if(all(target_arch = "arm", not(target_os = "ios"), not(thumbv6m)))] #[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 { pub extern "C" fn __divsi3(a: i32, b: i32) -> i32 {
a.div(b) a.div(b)
} }

View File

@ -66,6 +66,7 @@ impl Lshr for u128 {}
intrinsics! { intrinsics! {
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] #[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 { pub extern "C" fn __ashldi3(a: u64, b: u32) -> u64 {
a.ashl(b) a.ashl(b)
} }
@ -75,6 +76,7 @@ intrinsics! {
} }
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] #[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 { pub extern "C" fn __ashrdi3(a: i64, b: u32) -> i64 {
a.ashr(b) a.ashr(b)
} }
@ -84,6 +86,7 @@ intrinsics! {
} }
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))] #[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 { pub extern "C" fn __lshrdi3(a: u64, b: u32) -> u64 {
a.lshr(b) a.lshr(b)
} }

View File

@ -155,6 +155,7 @@ intrinsics! {
#[use_c_shim_if(all(target_arch = "arm", #[use_c_shim_if(all(target_arch = "arm",
not(target_os = "ios"), not(target_os = "ios"),
not(thumbv6m)))] not(thumbv6m)))]
#[arm_aeabi_alias = __aeabi_uidiv]
/// Returns `n / d` /// Returns `n / d`
pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 { pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 {
// Special cases // Special cases

View File

@ -7,7 +7,7 @@ macro_rules! intrinsics {
// intrinsic. // intrinsic.
( (
#[use_c_shim_if($($cfg_clause:tt)*)] #[use_c_shim_if($($cfg_clause:tt)*)]
$(#[$attr:meta])* $(#[$($attr:tt)*])*
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty {
$($body:tt)* $($body:tt)*
} }
@ -16,7 +16,6 @@ macro_rules! intrinsics {
) => ( ) => (
#[cfg(all(feature = "c", $($cfg_clause)*))] #[cfg(all(feature = "c", $($cfg_clause)*))]
$(#[$attr])*
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
extern $abi { extern $abi {
fn $name($($argname: $ty),*) -> $ret; fn $name($($argname: $ty),*) -> $ret;
@ -28,7 +27,7 @@ macro_rules! intrinsics {
#[cfg(not(all(feature = "c", $($cfg_clause)*)))] #[cfg(not(all(feature = "c", $($cfg_clause)*)))]
intrinsics! { intrinsics! {
$(#[$attr])* $(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
$($body)* $($body)*
} }
@ -42,7 +41,7 @@ macro_rules! intrinsics {
// ARM and `"C"` elsewhere. // ARM and `"C"` elsewhere.
( (
#[aapcs_on_arm] #[aapcs_on_arm]
$(#[$attr:meta])* $(#[$($attr:tt)*])*
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty {
$($body:tt)* $($body:tt)*
} }
@ -51,7 +50,7 @@ macro_rules! intrinsics {
) => ( ) => (
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]
intrinsics! { intrinsics! {
$(#[$attr])* $(#[$($attr)*])*
pub extern "aapcs" fn $name( $($argname: $ty),* ) -> $ret { pub extern "aapcs" fn $name( $($argname: $ty),* ) -> $ret {
$($body)* $($body)*
} }
@ -59,7 +58,7 @@ macro_rules! intrinsics {
#[cfg(not(target_arch = "arm"))] #[cfg(not(target_arch = "arm"))]
intrinsics! { intrinsics! {
$(#[$attr])* $(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
$($body)* $($body)*
} }
@ -72,7 +71,7 @@ macro_rules! intrinsics {
// win64 for some methods. // win64 for some methods.
( (
#[unadjusted_on_win64] #[unadjusted_on_win64]
$(#[$attr:meta])* $(#[$($attr:tt)*])*
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty {
$($body:tt)* $($body:tt)*
} }
@ -81,7 +80,7 @@ macro_rules! intrinsics {
) => ( ) => (
#[cfg(all(windows, target_pointer_width = "64"))] #[cfg(all(windows, target_pointer_width = "64"))]
intrinsics! { intrinsics! {
$(#[$attr])* $(#[$($attr)*])*
pub extern "unadjusted" fn $name( $($argname: $ty),* ) -> $ret { pub extern "unadjusted" fn $name( $($argname: $ty),* ) -> $ret {
$($body)* $($body)*
} }
@ -89,7 +88,7 @@ macro_rules! intrinsics {
#[cfg(not(all(windows, target_pointer_width = "64")))] #[cfg(not(all(windows, target_pointer_width = "64")))]
intrinsics! { intrinsics! {
$(#[$attr])* $(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
$($body)* $($body)*
} }
@ -102,7 +101,7 @@ macro_rules! intrinsics {
// bit calling convention correct. // bit calling convention correct.
( (
#[win64_128bit_abi_hack] #[win64_128bit_abi_hack]
$(#[$attr:meta])* $(#[$($attr:tt)*])*
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty { pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty {
$($body:tt)* $($body:tt)*
} }
@ -110,7 +109,7 @@ macro_rules! intrinsics {
$($rest:tt)* $($rest:tt)*
) => ( ) => (
#[cfg(all(windows, target_pointer_width = "64"))] #[cfg(all(windows, target_pointer_width = "64"))]
$(#[$attr])* $(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
$($body)* $($body)*
} }
@ -130,7 +129,49 @@ macro_rules! intrinsics {
#[cfg(not(all(windows, target_pointer_width = "64")))] #[cfg(not(all(windows, target_pointer_width = "64")))]
intrinsics! { 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 { pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
$($body)* $($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 { pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty {
$($body:tt)* $($body:tt)*
} }
$($rest:tt)* $($rest:tt)*
) => ( ) => (
$(#[$attr])* $(#[$($attr)*])*
#[cfg_attr(not(test), no_mangle)] #[cfg_attr(not(test), no_mangle)]
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret { pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
$($body)* $($body)*