1use crate::Sysno;
2
3use core::arch::asm;
4
5#[inline(always)]
6unsafe fn callee() -> usize {
7 (*crate::env::vdso::VDSO.get()).0.vsyscall as usize
8}
9
10#[inline(always)]
11unsafe fn vsyscall0(sysno: Sysno) -> usize {
12 let ret;
13 asm!(
14 "call {callee}",
15 callee = in(reg) callee(),
16 inlateout("rax") sysno as usize => ret,
17 options(preserves_flags)
18 );
19 ret
20}
21
22#[inline(always)]
23unsafe fn vsyscall1(sysno: Sysno, arg0: usize) -> usize {
24 let ret: usize;
25 asm!(
26 "call {callee}",
27 callee = in(reg) callee(),
28 inlateout("eax") sysno as usize => ret,
29 in("ebx") arg0,
30 options(preserves_flags)
31 );
32 ret
33}
34
35#[inline(always)]
36unsafe fn vsyscall1_noreturn(sysno: Sysno, arg0: usize) -> ! {
37 asm!(
38 "call {callee}",
39 "ud2",
40 callee = in(reg) callee(),
41 in("eax") sysno as usize,
42 in("ebx") arg0,
43 options(noreturn)
44 )
45}
46
47#[inline(always)]
48unsafe fn vsyscall2(sysno: Sysno, arg0: usize, arg1: usize) -> usize {
49 let ret: usize;
50 asm!(
51 "call {callee}",
52 callee = in(reg) callee(),
53 inlateout("eax") sysno as usize => ret,
54 in("ebx") arg0,
55 in("ecx") arg1,
56 options(preserves_flags)
57 );
58 ret
59}
60
61#[inline(always)]
62unsafe fn vsyscall3(sysno: Sysno, arg0: usize, arg1: usize, arg2: usize) -> usize {
63 let ret: usize;
64 asm!(
65 "call {callee}",
66 callee = in(reg) callee(),
67 inlateout("eax") sysno as usize => ret,
68 in("ebx") arg0,
69 in("ecx") arg1,
70 in("edx") arg2,
71 options(preserves_flags)
72 );
73 ret
74}
75
76#[inline(always)]
77unsafe fn vsyscall4(sysno: Sysno, arg0: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
78 let ret: usize;
79 asm!(
80 "xchg esi, {arg3}",
81 "call edi",
82 "xchg esi, {arg3}",
83 arg3 = in(reg) arg3,
84 in("edi") callee(),
85 inlateout("eax") sysno as usize => ret,
86 in("ebx") arg0,
87 in("ecx") arg1,
88 in("edx") arg2,
89 options(preserves_flags)
90 );
91 ret
92}
93
94#[inline(always)]
95unsafe fn vsyscall5(
96 sysno: Sysno,
97 arg0: usize,
98 arg1: usize,
99 arg2: usize,
100 arg3: usize,
101 arg4: usize,
102) -> usize {
103 let ret: usize;
106 asm!(
107 "push esi",
109
110 "push DWORD PTR [eax]",
112 "mov esi, DWORD PTR [eax+4]",
113 "mov eax, DWORD PTR [eax+8]",
114 "call DWORD PTR [esp]",
115
116 "pop esi",
118
119 "pop esi",
121 inout("eax") &[callee(), arg3, sysno as usize] => ret,
122 in("ebx") arg0,
123 in("ecx") arg1,
124 in("edx") arg2,
125 in("edi") arg4,
126 options(preserves_flags)
127 );
128 ret
129}
130
131#[inline(always)]
132unsafe fn vsyscall6(
133 sysno: Sysno,
134 arg0: usize,
135 arg1: usize,
136 arg2: usize,
137 arg3: usize,
138 arg4: usize,
139 arg5: usize,
140) -> usize {
141 let ret: usize;
144 asm!(
145 "push ebp",
147 "push esi",
148
149 "push DWORD PTR [eax]",
151 "mov esi, DWORD PTR [eax+4]",
152 "mov ebp, DWORD PTR [eax+8]",
153 "mov eax, DWORD PTR [eax+12]",
154 "call DWORD PTR [esp]",
155
156 "pop esi",
158
159 "pop esi",
161 "pop ebp",
162 inout("eax") &[callee(), arg3, arg5, sysno as usize] => ret,
163 in("ebx") arg0,
164 in("ecx") arg1,
165 in("edx") arg2,
166 in("edi") arg4,
167 options(preserves_flags)
168 );
169 ret
170}
171
172#[allow(clippy::missing_safety_doc)]
173#[inline(always)]
174pub unsafe fn raw_syscall0(sysno: Sysno) -> usize {
175 if callee() == 0 {
176 let ret;
177 asm!(
178 "int $$0x80",
179 inlateout("eax") sysno as usize => ret,
180 options(nostack, preserves_flags, readonly)
181 );
182 ret
183 } else {
184 vsyscall0(sysno)
185 }
186}
187
188pub use raw_syscall0 as raw_syscall0_readonly;
189
190#[allow(clippy::missing_safety_doc)]
191pub unsafe fn raw_syscall1(sysno: Sysno, arg0: usize) -> usize {
192 if callee() == 0 {
193 let ret;
194 asm!(
195 "int $$0x80",
196 inlateout("eax") sysno as usize => ret,
197 in("ebx") arg0,
198 options(nostack, preserves_flags)
199 );
200 ret
201 } else {
202 vsyscall1(sysno, arg0)
203 }
204}
205
206#[allow(clippy::missing_safety_doc)]
207pub unsafe fn raw_syscall1_readonly(sysno: Sysno, arg0: usize) -> usize {
208 if callee() == 0 {
209 let ret;
210 asm!(
211 "int $$0x80",
212 inlateout("eax") sysno as usize => ret,
213 in("ebx") arg0,
214 options(nostack, preserves_flags, readonly)
215 );
216 ret
217 } else {
218 vsyscall1(sysno, arg0)
219 }
220}
221
222#[allow(clippy::missing_safety_doc)]
223pub unsafe fn syscall1_noreturn(sysno: Sysno, arg0: usize) -> ! {
224 if callee() == 0 {
225 asm!(
226 "int $$0x80",
227 "ud2",
228 in("eax") sysno as usize,
229 in("ebx") arg0,
230 options(noreturn)
231 )
232 } else {
233 vsyscall1_noreturn(sysno, arg0)
234 }
235}
236
237#[allow(clippy::missing_safety_doc)]
238pub unsafe fn raw_syscall2(sysno: Sysno, arg0: usize, arg1: usize) -> usize {
239 if callee() == 0 {
240 let ret;
241 asm!(
242 "int $$0x80",
243 inlateout("eax") sysno as usize => ret,
244 in("ebx") arg0,
245 in("ecx") arg1,
246 options(nostack, preserves_flags)
247 );
248 ret
249 } else {
250 vsyscall2(sysno, arg0, arg1)
251 }
252}
253
254#[allow(clippy::missing_safety_doc)]
255pub unsafe fn raw_syscall2_readonly(sysno: Sysno, arg0: usize, arg1: usize) -> usize {
256 if callee() == 0 {
257 let ret;
258 asm!(
259 "int $$0x80",
260 inlateout("eax") sysno as usize => ret,
261 in("ebx") arg0,
262 in("ecx") arg1,
263 options(nostack, preserves_flags, readonly)
264 );
265 ret
266 } else {
267 vsyscall2(sysno, arg0, arg1)
268 }
269}
270
271#[allow(clippy::missing_safety_doc)]
272pub unsafe fn raw_syscall3(sysno: Sysno, arg0: usize, arg1: usize, arg2: usize) -> usize {
273 if callee() == 0 {
274 let ret;
275 asm!(
276 "int $$0x80",
277 inlateout("eax") sysno as usize => ret,
278 in("ebx") arg0,
279 in("ecx") arg1,
280 in("edx") arg2,
281 options(nostack, preserves_flags)
282 );
283 ret
284 } else {
285 vsyscall3(sysno, arg0, arg1, arg2)
286 }
287}
288
289#[allow(clippy::missing_safety_doc)]
290pub unsafe fn raw_syscall3_readonly(sysno: Sysno, arg0: usize, arg1: usize, arg2: usize) -> usize {
291 if callee() == 0 {
292 let ret;
293 asm!(
294 "int $$0x80",
295 inlateout("eax") sysno as usize => ret,
296 in("ebx") arg0,
297 in("ecx") arg1,
298 in("edx") arg2,
299 options(nostack, preserves_flags, readonly)
300 );
301 ret
302 } else {
303 vsyscall3(sysno, arg0, arg1, arg2)
304 }
305}
306
307#[allow(clippy::missing_safety_doc)]
308pub unsafe fn raw_syscall4(
309 sysno: Sysno,
310 arg0: usize,
311 arg1: usize,
312 arg2: usize,
313 arg3: usize,
314) -> usize {
315 if callee() == 0 {
316 let ret;
317 asm!(
320 "xchg esi, {arg3}",
321 "int $$0x80",
322 "xchg esi, {arg3}",
323 arg3 = in(reg) arg3,
324 inlateout("eax") sysno as usize => ret,
325 in("ebx") arg0,
326 in("ecx") arg1,
327 in("edx") arg2,
328 options(nostack, preserves_flags)
329 );
330 ret
331 } else {
332 vsyscall4(sysno, arg0, arg1, arg2, arg3)
333 }
334}
335
336#[allow(clippy::missing_safety_doc)]
337pub unsafe fn raw_syscall4_readonly(
338 sysno: Sysno,
339 arg0: usize,
340 arg1: usize,
341 arg2: usize,
342 arg3: usize,
343) -> usize {
344 if callee() == 0 {
345 let ret;
346 asm!(
347 "xchg esi, {arg3}",
348 "int $$0x80",
349 "xchg esi, {arg3}",
350 arg3 = in(reg) arg3,
351 inlateout("eax") sysno as usize => ret,
352 in("ebx") arg0,
353 in("ecx") arg1,
354 in("edx") arg2,
355 options(nostack, preserves_flags, readonly)
356 );
357 ret
358 } else {
359 vsyscall4(sysno, arg0, arg1, arg2, arg3)
360 }
361}
362
363#[allow(clippy::missing_safety_doc)]
364pub unsafe fn raw_syscall5(
365 sysno: Sysno,
366 arg0: usize,
367 arg1: usize,
368 arg2: usize,
369 arg3: usize,
370 arg4: usize,
371) -> usize {
372 if callee() == 0 {
373 let ret;
374 asm!(
375 "xchg esi, {arg3}",
376 "int $$0x80",
377 "xchg esi, {arg3}",
378 arg3 = in(reg) arg3,
379 inlateout("eax") sysno as usize => ret,
380 in("ebx") arg0,
381 in("ecx") arg1,
382 in("edx") arg2,
383 in("edi") arg4,
384 options(nostack, preserves_flags)
385 );
386 ret
387 } else {
388 vsyscall5(sysno, arg0, arg1, arg2, arg3, arg4)
389 }
390}
391
392#[allow(clippy::missing_safety_doc)]
393pub unsafe fn raw_syscall5_readonly(
394 sysno: Sysno,
395 arg0: usize,
396 arg1: usize,
397 arg2: usize,
398 arg3: usize,
399 arg4: usize,
400) -> usize {
401 if callee() == 0 {
402 let ret;
403 asm!(
404 "xchg esi, {arg3}",
405 "int $$0x80",
406 "xchg esi, {arg3}",
407 arg3 = in(reg) arg3,
408 inlateout("eax") sysno as usize => ret,
409 in("ebx") arg0,
410 in("ecx") arg1,
411 in("edx") arg2,
412 in("edi") arg4,
413 options(nostack, preserves_flags, readonly)
414 );
415 ret
416 } else {
417 vsyscall5(sysno, arg0, arg1, arg2, arg3, arg4)
418 }
419}
420
421#[allow(clippy::missing_safety_doc)]
422pub unsafe fn raw_syscall6(
423 sysno: Sysno,
424 arg0: usize,
425 arg1: usize,
426 arg2: usize,
427 arg3: usize,
428 arg4: usize,
429 arg5: usize,
430) -> usize {
431 if callee() == 0 {
432 let ret;
433 asm!(
439 "push ebp",
440 "push esi",
441 "mov esi, DWORD PTR [eax]",
442 "mov ebp, DWORD PTR [eax+4]",
443 "mov eax, DWORD PTR [eax+8]",
444 "int $$0x80",
445 "pop esi",
446 "pop ebp",
447 inlateout("eax") &[arg3, arg5, sysno as usize] => ret,
448 in("ebx") arg0,
449 in("ecx") arg1,
450 in("edx") arg2,
451 in("edi") arg4,
452 options(preserves_flags)
453 );
454 ret
455 } else {
456 vsyscall6(sysno, arg0, arg1, arg2, arg3, arg4, arg5)
457 }
458}
459
460#[allow(clippy::missing_safety_doc)]
461pub unsafe fn raw_syscall6_readonly(
462 sysno: Sysno,
463 arg0: usize,
464 arg1: usize,
465 arg2: usize,
466 arg3: usize,
467 arg4: usize,
468 arg5: usize,
469) -> usize {
470 if callee() == 0 {
471 let ret;
472 asm!(
473 "push ebp",
474 "push esi",
475 "mov esi, DWORD PTR [eax]",
476 "mov ebp, DWORD PTR [eax+4]",
477 "mov eax, DWORD PTR [eax+8]",
478 "int $$0x80",
479 "pop esi",
480 "pop ebp",
481 inlateout("eax") &[arg3, arg5, sysno as usize] => ret,
482 in("ebx") arg0,
483 in("ecx") arg1,
484 in("edx") arg2,
485 in("edi") arg4,
486 options(preserves_flags, readonly)
487 );
488 ret
489 } else {
490 vsyscall6(sysno, arg0, arg1, arg2, arg3, arg4, arg5)
491 }
492}
493
494include!("_syscalls.rs");
495
496#[inline(always)]
497pub(crate) fn init() {}