From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../rustix/src/imp/linux_raw/arch/outline/x86.rs | 285 +++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/x86.rs (limited to 'vendor/rustix/src/imp/linux_raw/arch/outline/x86.rs') diff --git a/vendor/rustix/src/imp/linux_raw/arch/outline/x86.rs b/vendor/rustix/src/imp/linux_raw/arch/outline/x86.rs new file mode 100644 index 000000000..938a4a09d --- /dev/null +++ b/vendor/rustix/src/imp/linux_raw/arch/outline/x86.rs @@ -0,0 +1,285 @@ +//! Syscall wrappers for 32-bit x86. +//! +//! This module is similar to the `nr_last` module, except specialized for +//! 32-bit x86. +//! +//! The syscall convention passes all arguments in registers. The closest we +//! can easily get to that from Rust is to use the fastcall convention which +//! passes the first two arguments in `ecx` and `edx`, which are the second +//! and third Linux syscall arguments. To line them up, this function passes +//! the second and third syscall argument as the first and second argument to +//! the outline assembly, followed by the first syscall argument, and then the +//! rest of the syscall arguments. The assembly code still has to do some work, +//! but at least we can get up to two arguments into the right place for it. + +#![allow(dead_code, unused_imports)] + +use crate::imp::reg::{ArgReg, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; +use crate::imp::vdso_wrappers::SyscallType; + +// First we declare the actual assembly routines with `*_nr_last_fastcall` +// names and reordered arguments. If the signatures or calling conventions are +// ever changed, the symbol names should also be updated accordingly, to avoid +// collisions with other versions of this crate. +// +// We don't define `_readonly` versions of these because we have no way to tell +// Rust that calls to our outline assembly are readonly. +extern "fastcall" { + fn rustix_syscall0_nr_last_fastcall(nr: SyscallNumber<'_>) -> RetReg; + fn rustix_syscall1_nr_last_fastcall(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> RetReg; + fn rustix_syscall1_noreturn_nr_last_fastcall(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> !; + fn rustix_syscall2_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall3_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall4_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall5_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall6_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, + nr: SyscallNumber<'_>, + ) -> RetReg; +} + +// Then we define inline wrapper functions that do the reordering. + +#[inline] +pub(in crate::imp) unsafe fn syscall0(nr: SyscallNumber<'_>) -> RetReg { + rustix_syscall0_nr_last_fastcall(nr) +} +#[inline] +pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + rustix_syscall1_nr_last_fastcall(a0, nr) +} +#[inline] +pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + rustix_syscall1_noreturn_nr_last_fastcall(a0, nr) +} +#[inline] +pub(in crate::imp) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + rustix_syscall2_nr_last_fastcall(a1, a0, nr) +} +#[inline] +pub(in crate::imp) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + rustix_syscall3_nr_last_fastcall(a1, a2, a0, nr) +} +#[inline] +pub(in crate::imp) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + rustix_syscall4_nr_last_fastcall(a1, a2, a0, a3, nr) +} +#[inline] +pub(in crate::imp) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + rustix_syscall5_nr_last_fastcall(a1, a2, a0, a3, a4, nr) +} +#[inline] +pub(in crate::imp) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + rustix_syscall6_nr_last_fastcall(a1, a2, a0, a3, a4, a5, nr) +} + +// Then we define the `_readonly` versions of the wrappers. We don't have +// separate `_readonly` implementations, so these can just be aliases to +// their non-`_readonly` counterparts. +pub(in crate::imp) use { + syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, syscall2 as syscall2_readonly, + syscall3 as syscall3_readonly, syscall4 as syscall4_readonly, syscall5 as syscall5_readonly, + syscall6 as syscall6_readonly, +}; + +// x86 prefers to route all syscalls through the vDSO, though this isn't +// always possible, so it also has a special form for doing the dispatch. +// +// First we declare the actual assembly routines with `*_nr_last_fastcall` +// names and reordered arguments. If the signatures or calling conventions are +// ever changed, the symbol names should also be updated accordingly, to avoid +// collisions with other versions of this crate. +extern "fastcall" { + fn rustix_indirect_syscall0_nr_last_fastcall( + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall1_nr_last_fastcall( + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall1_noreturn_nr_last_fastcall( + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> !; + fn rustix_indirect_syscall2_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall3_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall4_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall5_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall6_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; +} + +// Then we define inline wrapper functions that do the reordering. + +#[inline] +pub(in crate::imp) unsafe fn indirect_syscall0( + callee: SyscallType, + nr: SyscallNumber<'_>, +) -> RetReg { + rustix_indirect_syscall0_nr_last_fastcall(nr, callee) +} +#[inline] +pub(in crate::imp) unsafe fn indirect_syscall1( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + rustix_indirect_syscall1_nr_last_fastcall(a0, nr, callee) +} +#[inline] +pub(in crate::imp) unsafe fn indirect_syscall1_noreturn( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> ! { + rustix_indirect_syscall1_noreturn_nr_last_fastcall(a0, nr, callee) +} +#[inline] +pub(in crate::imp) unsafe fn indirect_syscall2( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + rustix_indirect_syscall2_nr_last_fastcall(a1, a0, nr, callee) +} +#[inline] +pub(in crate::imp) unsafe fn indirect_syscall3( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + rustix_indirect_syscall3_nr_last_fastcall(a1, a2, a0, nr, callee) +} +#[inline] +pub(in crate::imp) unsafe fn indirect_syscall4( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + rustix_indirect_syscall4_nr_last_fastcall(a1, a2, a0, a3, nr, callee) +} +#[inline] +pub(in crate::imp) unsafe fn indirect_syscall5( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + rustix_indirect_syscall5_nr_last_fastcall(a1, a2, a0, a3, a4, nr, callee) +} +#[inline] +pub(in crate::imp) unsafe fn indirect_syscall6( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + rustix_indirect_syscall6_nr_last_fastcall(a1, a2, a0, a3, a4, a5, nr, callee) +} -- cgit v1.2.3