1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// SPDX-License-Identifier: MIT
// Copyright 2024 IROX Contributors

//!
//! Core syscall structures & macros
//!
//!  *
//!  * Registers on entry:
//!  * rax  system call number
//!  * rcx  return address
//!  * r11  saved rflags (note: r11 is callee-clobbered register in C ABI)
//!  * rdi  arg0
//!  * rsi  arg1
//!  * rdx  arg2
//!  * r10  arg3 (needs to be moved to rcx to conform to C ABI)
//!  * r8   arg4
//!  * r9   arg5
//!  * (note: r12-r15, rbp, rbx are callee-preserved in C ABI)
//!

use core::arch::asm;
pub unsafe fn syscall_x64_6(
    num: u64,
    arg0: u64,
    arg1: u64,
    arg2: u64,
    arg3: u64,
    arg4: u64,
    arg5: u64,
) -> u64 {
    let mut ret: u64;
    asm!(
    "syscall",
    in("rax") num,
    in("rdi") arg0,
    in("rsi") arg1,
    in("rdx") arg2,
    in("r10") arg3, // this is usually rcx
    in("r8") arg4,
    in("r9") arg5,
    out("rcx") _, // clobber return address in rcx
    out("r11") _, // clobber saved rflags in r11
    lateout("rax") ret, // return value
    );
    ret
}
pub unsafe fn syscall_x64_5(
    num: u64,
    arg0: u64,
    arg1: u64,
    arg2: u64,
    arg3: u64,
    arg4: u64,
) -> u64 {
    let mut ret: u64;
    asm!(
    "syscall",
    in("rax") num,
    in("rdi") arg0,
    in("rsi") arg1,
    in("rdx") arg2,
    in("r10") arg3, // this is usually rcx
    in("r8") arg4,
    out("rcx") _, // clobber return address in rcx
    out("r11") _, // clobber saved rflags in r11
    lateout("rax") ret, // return value
    );
    ret
}
pub unsafe fn syscall_x64_4(num: u64, arg0: u64, arg1: u64, arg2: u64, arg3: u64) -> u64 {
    let mut ret: u64;
    asm!(
    "syscall",
    in("rax") num,
    in("rdi") arg0,
    in("rsi") arg1,
    in("rdx") arg2,
    in("r10") arg3, // this is usually rcx
    out("rcx") _, // clobber return address in rcx
    out("r11") _, // clobber saved rflags in r11
    lateout("rax") ret, // return value
    );
    ret
}
pub unsafe fn syscall_x64_3(num: u64, arg0: u64, arg1: u64, arg2: u64) -> u64 {
    let mut ret: u64;
    asm!(
    "syscall",
    in("rax") num,
    in("rdi") arg0,
    in("rsi") arg1,
    in("rdx") arg2,
    out("rcx") _, // clobber return address in rcx
    out("r11") _, // clobber saved rflags in r11
    lateout("rax") ret, // return value
    );
    ret
}
pub unsafe fn syscall_x64_2(num: u64, arg0: u64, arg1: u64) -> u64 {
    let mut ret: u64;
    asm!(
    "syscall",
    in("rax") num,
    in("rdi") arg0,
    in("rsi") arg1,
    out("rcx") _, // clobber return address in rcx
    out("r11") _, // clobber saved rflags in r11
    lateout("rax") ret, // return value
    );
    ret
}

pub unsafe fn syscall_x64_1(num: u64, arg1: u64) -> u64 {
    let mut ret: u64;
    asm!(
    "syscall",
    in("rax") num,
    in("rdi") arg1,
    out("rcx") _, // clobber return address in rcx
    out("r11") _, // clobber saved rflags in r11
    lateout("rax") ret, // return value
    );
    ret
}

pub unsafe fn syscall_x64_0(num: u64) -> u64 {
    let mut ret: u64;
    asm!(
        "syscall",
        in("rax") num,
        out("rcx") _, // clobber return address in rcx
        out("r11") _, // clobber saved rflags in r11
        lateout("rax") ret, // return value
    );
    ret
}

#[macro_export]
macro_rules! syscall_1 {
    ($num:ident, $arg0:expr) => {
        {
            let mut ret: i64;
            core::arch::asm!(
                "syscall",
                in("rax") $num,
                in("rdi") $arg0,
                out("rcx") _, // clobber return address in rcx
                out("r11") _, // clobber saved rflags in r11
                lateout("rax") ret, // return value
                );
            ret
        }
    };
}
#[macro_export]
macro_rules! syscall_2 {
    ($num:ident, $arg0:expr, $arg1:expr) => {
        {
            let mut ret: i64;
            core::arch::asm!(
                "syscall",
                in("rax") $num,
                in("rdi") $arg0,
                in("rsi") $arg1,
                out("rcx") _, // clobber return address in rcx
                out("r11") _, // clobber saved rflags in r11
                lateout("rax") ret, // return value
                );
            ret
        }
    };
}