irox_safe_linux/
syscall.rs

1// SPDX-License-Identifier: MIT
2// Copyright 2024 IROX Contributors
3
4//!
5//! Core syscall structures & macros
6//!
7//!  *
8//!  * Registers on entry:
9//!  * rax  system call number
10//!  * rcx  return address
11//!  * r11  saved rflags (note: r11 is callee-clobbered register in C ABI)
12//!  * rdi  arg0
13//!  * rsi  arg1
14//!  * rdx  arg2
15//!  * r10  arg3 (needs to be moved to rcx to conform to C ABI)
16//!  * r8   arg4
17//!  * r9   arg5
18//!  * (note: r12-r15, rbp, rbx are callee-preserved in C ABI)
19//!
20
21use core::arch::asm;
22pub unsafe fn syscall_x64_6(
23    num: u64,
24    arg0: u64,
25    arg1: u64,
26    arg2: u64,
27    arg3: u64,
28    arg4: u64,
29    arg5: u64,
30) -> u64 {
31    let mut ret: u64;
32    asm!(
33    "syscall",
34    in("rax") num,
35    in("rdi") arg0,
36    in("rsi") arg1,
37    in("rdx") arg2,
38    in("r10") arg3, // this is usually rcx
39    in("r8") arg4,
40    in("r9") arg5,
41    out("rcx") _, // clobber return address in rcx
42    out("r11") _, // clobber saved rflags in r11
43    lateout("rax") ret, // return value
44    );
45    ret
46}
47pub unsafe fn syscall_x64_5(
48    num: u64,
49    arg0: u64,
50    arg1: u64,
51    arg2: u64,
52    arg3: u64,
53    arg4: u64,
54) -> u64 {
55    let mut ret: u64;
56    asm!(
57    "syscall",
58    in("rax") num,
59    in("rdi") arg0,
60    in("rsi") arg1,
61    in("rdx") arg2,
62    in("r10") arg3, // this is usually rcx
63    in("r8") arg4,
64    out("rcx") _, // clobber return address in rcx
65    out("r11") _, // clobber saved rflags in r11
66    lateout("rax") ret, // return value
67    );
68    ret
69}
70pub unsafe fn syscall_x64_4(num: u64, arg0: u64, arg1: u64, arg2: u64, arg3: u64) -> u64 {
71    let mut ret: u64;
72    asm!(
73    "syscall",
74    in("rax") num,
75    in("rdi") arg0,
76    in("rsi") arg1,
77    in("rdx") arg2,
78    in("r10") arg3, // this is usually rcx
79    out("rcx") _, // clobber return address in rcx
80    out("r11") _, // clobber saved rflags in r11
81    lateout("rax") ret, // return value
82    );
83    ret
84}
85pub unsafe fn syscall_x64_3(num: u64, arg0: u64, arg1: u64, arg2: u64) -> u64 {
86    let mut ret: u64;
87    asm!(
88    "syscall",
89    in("rax") num,
90    in("rdi") arg0,
91    in("rsi") arg1,
92    in("rdx") arg2,
93    out("rcx") _, // clobber return address in rcx
94    out("r11") _, // clobber saved rflags in r11
95    lateout("rax") ret, // return value
96    );
97    ret
98}
99pub unsafe fn syscall_x64_2(num: u64, arg0: u64, arg1: u64) -> u64 {
100    let mut ret: u64;
101    asm!(
102    "syscall",
103    in("rax") num,
104    in("rdi") arg0,
105    in("rsi") arg1,
106    out("rcx") _, // clobber return address in rcx
107    out("r11") _, // clobber saved rflags in r11
108    lateout("rax") ret, // return value
109    );
110    ret
111}
112
113pub unsafe fn syscall_x64_1(num: u64, arg1: u64) -> u64 {
114    let mut ret: u64;
115    asm!(
116    "syscall",
117    in("rax") num,
118    in("rdi") arg1,
119    out("rcx") _, // clobber return address in rcx
120    out("r11") _, // clobber saved rflags in r11
121    lateout("rax") ret, // return value
122    );
123    ret
124}
125
126pub unsafe fn syscall_x64_0(num: u64) -> u64 {
127    let mut ret: u64;
128    asm!(
129        "syscall",
130        in("rax") num,
131        out("rcx") _, // clobber return address in rcx
132        out("r11") _, // clobber saved rflags in r11
133        lateout("rax") ret, // return value
134    );
135    ret
136}
137
138#[macro_export]
139macro_rules! syscall_1 {
140    ($num:ident, $arg0:expr) => {
141        {
142            let mut ret: i64;
143            core::arch::asm!(
144                "syscall",
145                in("rax") $num,
146                in("rdi") $arg0,
147                out("rcx") _, // clobber return address in rcx
148                out("r11") _, // clobber saved rflags in r11
149                lateout("rax") ret, // return value
150                );
151            ret
152        }
153    };
154}
155#[macro_export]
156macro_rules! syscall_2 {
157    ($num:ident, $arg0:expr, $arg1:expr) => {
158        {
159            let mut ret: i64;
160            core::arch::asm!(
161                "syscall",
162                in("rax") $num,
163                in("rdi") $arg0,
164                in("rsi") $arg1,
165                out("rcx") _, // clobber return address in rcx
166                out("r11") _, // clobber saved rflags in r11
167                lateout("rax") ret, // return value
168                );
169            ret
170        }
171    };
172}