linux_syscall/arch/x86_64/
syscall_asm.rs

1// Copyright (c) 2022 John Millikin <john@john-millikin.com>
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted.
5//
6// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
7// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
8// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
9// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
10// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
11// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
12// PERFORMANCE OF THIS SOFTWARE.
13//
14// SPDX-License-Identifier: 0BSD
15
16/// Linux syscall result for the `x86_64` architecture.
17#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
18#[must_use]
19pub struct Result(u64);
20
21impl Result {
22	#[inline]
23	pub const fn new(register_rax: u64) -> Self {
24		Self(register_rax)
25	}
26
27	#[inline]
28	pub const fn as_u64_unchecked(self) -> u64 {
29		self.0
30	}
31
32	#[inline]
33	pub const fn as_usize_unchecked(self) -> usize {
34		self.0 as usize
35	}
36}
37
38single_register_result64!(Result);
39
40#[cfg(not(doc))]
41#[macro_export]
42macro_rules! syscall {
43	($nr:expr $(,)?) => {{
44		let mut out_rax;
45		core::arch::asm!(
46			"syscall",
47			in("rax") u32::from(Into::<$crate::Syscall>::into($nr)),
48			out("rcx") _,
49			out("r11") _,
50			lateout("rax") out_rax,
51			options(nostack),
52		);
53		$crate::arch::x86_64::Result::new(out_rax)
54	}};
55	($nr:expr, $a1:expr $(,)?) => {{
56		let mut out_rax;
57		core::arch::asm!(
58			"syscall",
59			in("rax") u32::from(Into::<$crate::Syscall>::into($nr)),
60			in("rdi") $a1,
61			out("rcx") _,
62			out("r11") _,
63			lateout("rax") out_rax,
64			options(nostack),
65		);
66		$crate::arch::x86_64::Result::new(out_rax)
67	}};
68	($nr:expr, $a1:expr, $a2:expr $(,)?) => {{
69		let mut out_rax;
70		core::arch::asm!(
71			"syscall",
72			in("rax") u32::from(Into::<$crate::Syscall>::into($nr)),
73			in("rdi") $a1,
74			in("rsi") $a2,
75			out("rcx") _,
76			out("r11") _,
77			lateout("rax") out_rax,
78			options(nostack),
79		);
80		$crate::arch::x86_64::Result::new(out_rax)
81	}};
82	($nr:expr, $a1:expr, $a2:expr, $a3:expr $(,)?) => {{
83		let mut out_rax;
84		core::arch::asm!(
85			"syscall",
86			in("rax") u32::from(Into::<$crate::Syscall>::into($nr)),
87			in("rdi") $a1,
88			in("rsi") $a2,
89			in("rdx") $a3,
90			out("rcx") _,
91			out("r11") _,
92			lateout("rax") out_rax,
93			options(nostack),
94		);
95		$crate::arch::x86_64::Result::new(out_rax)
96	}};
97	($nr:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr $(,)?) => {{
98		let mut out_rax;
99		core::arch::asm!(
100			"syscall",
101			in("rax") u32::from(Into::<$crate::Syscall>::into($nr)),
102			in("rdi") $a1,
103			in("rsi") $a2,
104			in("rdx") $a3,
105			in("r10") $a4,
106			out("rcx") _,
107			out("r11") _,
108			lateout("rax") out_rax,
109			options(nostack),
110		);
111		$crate::arch::x86_64::Result::new(out_rax)
112	}};
113	($nr:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr $(,)?) => {{
114		let mut out_rax;
115		core::arch::asm!(
116			"syscall",
117			in("rax") u32::from(Into::<$crate::Syscall>::into($nr)),
118			in("rdi") $a1,
119			in("rsi") $a2,
120			in("rdx") $a3,
121			in("r10") $a4,
122			in("r8")  $a5,
123			out("rcx") _,
124			out("r11") _,
125			lateout("rax") out_rax,
126			options(nostack),
127		);
128		$crate::arch::x86_64::Result::new(out_rax)
129	}};
130	($nr:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr $(,)?) => {{
131		let mut out_rax;
132		core::arch::asm!(
133			"syscall",
134			in("rax") u32::from(Into::<$crate::Syscall>::into($nr)),
135			in("rdi") $a1,
136			in("rsi") $a2,
137			in("rdx") $a3,
138			in("r10") $a4,
139			in("r8")  $a5,
140			in("r9")  $a6,
141			out("rcx") _,
142			out("r11") _,
143			lateout("rax") out_rax,
144			options(nostack),
145		);
146		$crate::arch::x86_64::Result::new(out_rax)
147	}};
148}