diff --git a/compiler-builtins/src/aarch64.rs b/compiler-builtins/src/aarch64.rs index 80392187c..a72b30d29 100644 --- a/compiler-builtins/src/aarch64.rs +++ b/compiler-builtins/src/aarch64.rs @@ -5,7 +5,7 @@ use core::intrinsics; intrinsics! { #[unsafe(naked)] #[cfg(all(target_os = "uefi", not(feature = "no-asm")))] - pub unsafe extern "C" fn __chkstk() { + pub unsafe extern "custom" fn __chkstk() { core::arch::naked_asm!( ".p2align 2", "lsl x16, x15, #4", diff --git a/compiler-builtins/src/arm.rs b/compiler-builtins/src/arm.rs index 617cc8e50..fbec93ca4 100644 --- a/compiler-builtins/src/arm.rs +++ b/compiler-builtins/src/arm.rs @@ -9,11 +9,10 @@ unsafe extern "C" { } // SAFETY: these are defined in compiler-builtins -// FIXME(extern_custom), this isn't always the correct ABI -unsafe extern "aapcs" { +unsafe extern "custom" { // AAPCS is not always the correct ABI for these intrinsics, but we only use this to // forward another `__aeabi_` call so it doesn't matter. - fn __aeabi_idiv(a: i32, b: i32) -> i32; + fn __aeabi_idiv(); } intrinsics! { @@ -21,7 +20,7 @@ intrinsics! { // custom calling convention which can't be implemented using a normal Rust function. #[unsafe(naked)] #[cfg(not(target_env = "msvc"))] - pub unsafe extern "C" fn __aeabi_uidivmod() { + pub unsafe extern "custom" fn __aeabi_uidivmod() { core::arch::naked_asm!( "push {{lr}}", "sub sp, sp, #4", @@ -35,7 +34,7 @@ intrinsics! { } #[unsafe(naked)] - pub unsafe extern "C" fn __aeabi_uldivmod() { + pub unsafe extern "custom" fn __aeabi_uldivmod() { core::arch::naked_asm!( "push {{r4, lr}}", "sub sp, sp, #16", @@ -51,7 +50,7 @@ intrinsics! { } #[unsafe(naked)] - pub unsafe extern "C" fn __aeabi_idivmod() { + pub unsafe extern "custom" fn __aeabi_idivmod() { core::arch::naked_asm!( "push {{r0, r1, r4, lr}}", "bl {trampoline}", @@ -64,7 +63,7 @@ intrinsics! { } #[unsafe(naked)] - pub unsafe extern "C" fn __aeabi_ldivmod() { + pub unsafe extern "custom" fn __aeabi_ldivmod() { core::arch::naked_asm!( "push {{r4, lr}}", "sub sp, sp, #16", diff --git a/compiler-builtins/src/int/udiv.rs b/compiler-builtins/src/int/udiv.rs index b9dee63c4..017a81ac9 100644 --- a/compiler-builtins/src/int/udiv.rs +++ b/compiler-builtins/src/int/udiv.rs @@ -44,7 +44,7 @@ intrinsics! { } #[unsafe(naked)] - pub unsafe extern "C" fn __udivmodqi4() { + pub unsafe extern "custom" fn __udivmodqi4() { // compute unsigned 8-bit `n / d` and `n % d`. // // Note: GCC implements a [non-standard calling convention](https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention) for this function. diff --git a/compiler-builtins/src/lib.rs b/compiler-builtins/src/lib.rs index 1cec39d8b..dd9920cae 100644 --- a/compiler-builtins/src/lib.rs +++ b/compiler-builtins/src/lib.rs @@ -1,5 +1,6 @@ #![cfg_attr(feature = "compiler-builtins", compiler_builtins)] #![cfg_attr(all(target_family = "wasm"), feature(wasm_numeric_instr))] +#![feature(abi_custom)] #![feature(abi_unadjusted)] #![feature(asm_experimental_arch)] #![feature(cfg_target_has_atomic)] diff --git a/compiler-builtins/src/probestack.rs b/compiler-builtins/src/probestack.rs index 1441fd73b..1d0010842 100644 --- a/compiler-builtins/src/probestack.rs +++ b/compiler-builtins/src/probestack.rs @@ -52,15 +52,12 @@ // Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax, // ensuring that if any pages are unmapped we'll make a page fault. // -// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, -// it does not actually match `extern "C"`. -// // The ABI here is that the stack frame size is located in `%rax`. Upon // return we're not supposed to modify `%rsp` or `%rax`. #[cfg(target_arch = "x86_64")] #[unsafe(naked)] #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_probestack() { +pub unsafe extern "custom" fn __rust_probestack() { #[cfg(not(all(target_env = "sgx", target_vendor = "fortanix")))] macro_rules! ret { () => { @@ -144,13 +141,10 @@ pub unsafe extern "C" fn __rust_probestack() { // that on Unix we're expected to restore everything as it was, this // function basically can't tamper with anything. // -// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, -// it does not actually match `extern "C"`. -// // The ABI here is the same as x86_64, except everything is 32-bits large. #[unsafe(naked)] #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_probestack() { +pub unsafe extern "custom" fn __rust_probestack() { core::arch::naked_asm!( " .cfi_startproc @@ -192,9 +186,6 @@ pub unsafe extern "C" fn __rust_probestack() { // probestack function will also do things like _chkstk in MSVC. // So we need to sub %ax %sp in probestack when arch is x86. // -// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, -// it does not actually match `extern "C"`. -// // REF: Rust commit(74e80468347) // rust\src\llvm-project\llvm\lib\Target\X86\X86FrameLowering.cpp: 805 // Comments in LLVM: @@ -203,7 +194,7 @@ pub unsafe extern "C" fn __rust_probestack() { // themselves. #[unsafe(naked)] #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_probestack() { +pub unsafe extern "custom" fn __rust_probestack() { core::arch::naked_asm!( " .cfi_startproc diff --git a/compiler-builtins/src/x86.rs b/compiler-builtins/src/x86.rs index 01152d9c7..16e50922a 100644 --- a/compiler-builtins/src/x86.rs +++ b/compiler-builtins/src/x86.rs @@ -2,7 +2,7 @@ use core::intrinsics; -// NOTE These functions are implemented using assembly because they using a custom +// NOTE These functions are implemented using assembly because they use a custom // calling convention which can't be implemented using a normal Rust function // NOTE These functions are never mangled as they are not tested against compiler-rt @@ -13,10 +13,10 @@ intrinsics! { any(all(windows, target_env = "gnu"), target_os = "uefi"), not(feature = "no-asm") ))] - pub unsafe extern "C" fn __chkstk() { + pub unsafe extern "custom" fn __chkstk() { core::arch::naked_asm!( - "jmp __alloca", // Jump to __alloca since fallthrough may be unreliable" - options(att_syntax) + "jmp {}", // Jump to __alloca since fallthrough may be unreliable" + sym crate::x86::_alloca::_alloca, ); } @@ -25,7 +25,7 @@ intrinsics! { any(all(windows, target_env = "gnu"), target_os = "uefi"), not(feature = "no-asm") ))] - pub unsafe extern "C" fn _alloca() { + pub unsafe extern "custom" fn _alloca() { // __chkstk and _alloca are the same function core::arch::naked_asm!( "push %ecx", diff --git a/compiler-builtins/src/x86_64.rs b/compiler-builtins/src/x86_64.rs index fc1190f79..9b7133b48 100644 --- a/compiler-builtins/src/x86_64.rs +++ b/compiler-builtins/src/x86_64.rs @@ -2,7 +2,7 @@ use core::intrinsics; -// NOTE These functions are implemented using assembly because they using a custom +// NOTE These functions are implemented using assembly because they use a custom // calling convention which can't be implemented using a normal Rust function // NOTE These functions are never mangled as they are not tested against compiler-rt @@ -17,7 +17,7 @@ intrinsics! { ), not(feature = "no-asm") ))] - pub unsafe extern "C" fn ___chkstk_ms() { + pub unsafe extern "custom" fn ___chkstk_ms() { core::arch::naked_asm!( "push %rcx", "push %rax",