use extern "custom" on naked functions with a custom calling convention
This commit is contained in:
parent
3dc3017691
commit
a413cca7d3
7 changed files with 19 additions and 28 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue