rustix/backend/linux_raw/arch/
x86_64.rs

1//! x86-64 Linux system calls.
2
3use crate::backend::reg::{
4    ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0,
5};
6use core::arch::asm;
7
8#[cfg(target_pointer_width = "32")]
9compile_error!("x32 is not yet supported");
10
11#[inline]
12pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> {
13    let r0;
14    asm!(
15        "syscall",
16        inlateout("rax") nr.to_asm() => r0,
17        lateout("rcx") _,
18        lateout("r11") _,
19        options(nostack, preserves_flags, readonly)
20    );
21    FromAsm::from_asm(r0)
22}
23
24#[inline]
25pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> {
26    let r0;
27    asm!(
28        "syscall",
29        inlateout("rax") nr.to_asm() => r0,
30        in("rdi") a0.to_asm(),
31        lateout("rcx") _,
32        lateout("r11") _,
33        options(nostack, preserves_flags)
34    );
35    FromAsm::from_asm(r0)
36}
37
38#[inline]
39pub(in crate::backend) unsafe fn syscall1_readonly(
40    nr: SyscallNumber<'_>,
41    a0: ArgReg<'_, A0>,
42) -> RetReg<R0> {
43    let r0;
44    asm!(
45        "syscall",
46        inlateout("rax") nr.to_asm() => r0,
47        in("rdi") a0.to_asm(),
48        lateout("rcx") _,
49        lateout("r11") _,
50        options(nostack, preserves_flags, readonly)
51    );
52    FromAsm::from_asm(r0)
53}
54
55#[inline]
56pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! {
57    asm!(
58        "syscall",
59        in("rax") nr.to_asm(),
60        in("rdi") a0.to_asm(),
61        options(nostack, noreturn)
62    )
63}
64
65#[inline]
66pub(in crate::backend) unsafe fn syscall2(
67    nr: SyscallNumber<'_>,
68    a0: ArgReg<'_, A0>,
69    a1: ArgReg<'_, A1>,
70) -> RetReg<R0> {
71    let r0;
72    asm!(
73        "syscall",
74        inlateout("rax") nr.to_asm() => r0,
75        in("rdi") a0.to_asm(),
76        in("rsi") a1.to_asm(),
77        lateout("rcx") _,
78        lateout("r11") _,
79        options(nostack, preserves_flags)
80    );
81    FromAsm::from_asm(r0)
82}
83
84#[inline]
85pub(in crate::backend) unsafe fn syscall2_readonly(
86    nr: SyscallNumber<'_>,
87    a0: ArgReg<'_, A0>,
88    a1: ArgReg<'_, A1>,
89) -> RetReg<R0> {
90    let r0;
91    asm!(
92        "syscall",
93        inlateout("rax") nr.to_asm() => r0,
94        in("rdi") a0.to_asm(),
95        in("rsi") a1.to_asm(),
96        lateout("rcx") _,
97        lateout("r11") _,
98        options(nostack, preserves_flags, readonly)
99    );
100    FromAsm::from_asm(r0)
101}
102
103#[inline]
104pub(in crate::backend) unsafe fn syscall3(
105    nr: SyscallNumber<'_>,
106    a0: ArgReg<'_, A0>,
107    a1: ArgReg<'_, A1>,
108    a2: ArgReg<'_, A2>,
109) -> RetReg<R0> {
110    let r0;
111    asm!(
112        "syscall",
113        inlateout("rax") nr.to_asm() => r0,
114        in("rdi") a0.to_asm(),
115        in("rsi") a1.to_asm(),
116        in("rdx") a2.to_asm(),
117        lateout("rcx") _,
118        lateout("r11") _,
119        options(nostack, preserves_flags)
120    );
121    FromAsm::from_asm(r0)
122}
123
124#[inline]
125pub(in crate::backend) unsafe fn syscall3_readonly(
126    nr: SyscallNumber<'_>,
127    a0: ArgReg<'_, A0>,
128    a1: ArgReg<'_, A1>,
129    a2: ArgReg<'_, A2>,
130) -> RetReg<R0> {
131    let r0;
132    asm!(
133        "syscall",
134        inlateout("rax") nr.to_asm() => r0,
135        in("rdi") a0.to_asm(),
136        in("rsi") a1.to_asm(),
137        in("rdx") a2.to_asm(),
138        lateout("rcx") _,
139        lateout("r11") _,
140        options(nostack, preserves_flags, readonly)
141    );
142    FromAsm::from_asm(r0)
143}
144
145#[inline]
146pub(in crate::backend) unsafe fn syscall4(
147    nr: SyscallNumber<'_>,
148    a0: ArgReg<'_, A0>,
149    a1: ArgReg<'_, A1>,
150    a2: ArgReg<'_, A2>,
151    a3: ArgReg<'_, A3>,
152) -> RetReg<R0> {
153    let r0;
154    asm!(
155        "syscall",
156        inlateout("rax") nr.to_asm() => r0,
157        in("rdi") a0.to_asm(),
158        in("rsi") a1.to_asm(),
159        in("rdx") a2.to_asm(),
160        in("r10") a3.to_asm(),
161        lateout("rcx") _,
162        lateout("r11") _,
163        options(nostack, preserves_flags)
164    );
165    FromAsm::from_asm(r0)
166}
167
168#[inline]
169pub(in crate::backend) unsafe fn syscall4_readonly(
170    nr: SyscallNumber<'_>,
171    a0: ArgReg<'_, A0>,
172    a1: ArgReg<'_, A1>,
173    a2: ArgReg<'_, A2>,
174    a3: ArgReg<'_, A3>,
175) -> RetReg<R0> {
176    let r0;
177    asm!(
178        "syscall",
179        inlateout("rax") nr.to_asm() => r0,
180        in("rdi") a0.to_asm(),
181        in("rsi") a1.to_asm(),
182        in("rdx") a2.to_asm(),
183        in("r10") a3.to_asm(),
184        lateout("rcx") _,
185        lateout("r11") _,
186        options(nostack, preserves_flags, readonly)
187    );
188    FromAsm::from_asm(r0)
189}
190
191#[inline]
192pub(in crate::backend) unsafe fn syscall5(
193    nr: SyscallNumber<'_>,
194    a0: ArgReg<'_, A0>,
195    a1: ArgReg<'_, A1>,
196    a2: ArgReg<'_, A2>,
197    a3: ArgReg<'_, A3>,
198    a4: ArgReg<'_, A4>,
199) -> RetReg<R0> {
200    let r0;
201    asm!(
202        "syscall",
203        inlateout("rax") nr.to_asm() => r0,
204        in("rdi") a0.to_asm(),
205        in("rsi") a1.to_asm(),
206        in("rdx") a2.to_asm(),
207        in("r10") a3.to_asm(),
208        in("r8") a4.to_asm(),
209        lateout("rcx") _,
210        lateout("r11") _,
211        options(nostack, preserves_flags)
212    );
213    FromAsm::from_asm(r0)
214}
215
216#[inline]
217pub(in crate::backend) unsafe fn syscall5_readonly(
218    nr: SyscallNumber<'_>,
219    a0: ArgReg<'_, A0>,
220    a1: ArgReg<'_, A1>,
221    a2: ArgReg<'_, A2>,
222    a3: ArgReg<'_, A3>,
223    a4: ArgReg<'_, A4>,
224) -> RetReg<R0> {
225    let r0;
226    asm!(
227        "syscall",
228        inlateout("rax") nr.to_asm() => r0,
229        in("rdi") a0.to_asm(),
230        in("rsi") a1.to_asm(),
231        in("rdx") a2.to_asm(),
232        in("r10") a3.to_asm(),
233        in("r8") a4.to_asm(),
234        lateout("rcx") _,
235        lateout("r11") _,
236        options(nostack, preserves_flags, readonly)
237    );
238    FromAsm::from_asm(r0)
239}
240
241#[inline]
242pub(in crate::backend) unsafe fn syscall6(
243    nr: SyscallNumber<'_>,
244    a0: ArgReg<'_, A0>,
245    a1: ArgReg<'_, A1>,
246    a2: ArgReg<'_, A2>,
247    a3: ArgReg<'_, A3>,
248    a4: ArgReg<'_, A4>,
249    a5: ArgReg<'_, A5>,
250) -> RetReg<R0> {
251    let r0;
252    asm!(
253        "syscall",
254        inlateout("rax") nr.to_asm() => r0,
255        in("rdi") a0.to_asm(),
256        in("rsi") a1.to_asm(),
257        in("rdx") a2.to_asm(),
258        in("r10") a3.to_asm(),
259        in("r8") a4.to_asm(),
260        in("r9") a5.to_asm(),
261        lateout("rcx") _,
262        lateout("r11") _,
263        options(nostack, preserves_flags)
264    );
265    FromAsm::from_asm(r0)
266}
267
268#[inline]
269pub(in crate::backend) unsafe fn syscall6_readonly(
270    nr: SyscallNumber<'_>,
271    a0: ArgReg<'_, A0>,
272    a1: ArgReg<'_, A1>,
273    a2: ArgReg<'_, A2>,
274    a3: ArgReg<'_, A3>,
275    a4: ArgReg<'_, A4>,
276    a5: ArgReg<'_, A5>,
277) -> RetReg<R0> {
278    let r0;
279    asm!(
280        "syscall",
281        inlateout("rax") nr.to_asm() => r0,
282        in("rdi") a0.to_asm(),
283        in("rsi") a1.to_asm(),
284        in("rdx") a2.to_asm(),
285        in("r10") a3.to_asm(),
286        in("r8") a4.to_asm(),
287        in("r9") a5.to_asm(),
288        lateout("rcx") _,
289        lateout("r11") _,
290        options(nostack, preserves_flags, readonly)
291    );
292    FromAsm::from_asm(r0)
293}