#ifndef _LIBC_SYSDEP_H #define _LIBC_SYSDEP_H #include #include #include #include __BEGIN_DECLS static inline intptr_t _syscall_impl(sysid_t sysid, intptr_t p1, intptr_t p2, intptr_t p3, intptr_t p4, intptr_t p5) { intptr_t ret; #ifdef __i386__ asm volatile("push %%ebx;movl %2,%%ebx;int $0x80;pop %%ebx" : "=a"(ret) : "0"(sysid), "r"((intptr_t)(p1)), "c"((intptr_t)(p2)), "d"((intptr_t)(p3)), "S"((intptr_t)(p4)), "D"((intptr_t)(p5)) : "memory"); #elif __x86_64__ asm volatile( "movq %1, %%rax;\ movq %2, %%rdi;\ movq %3, %%rsi;\ movq %4, %%rdx;\ movq %5, %%r10;\ movq %6, %%r8;\ int $0x80;\ movq %%rax, %0;" : "=r"(ret) : "r"(sysid), "r"((intptr_t)(p1)), "r"((intptr_t)(p2)), "r"((intptr_t)(p3)), "r"((intptr_t)(p4)), "r"((intptr_t)(p5)) : "memory", "rax", "rdi", "rsi", "rdx", "r10", "r8"); #elif __arm__ asm volatile( "mov r7, %1;\ mov r0, %2;\ mov r1, %3;\ mov r2, %4;\ mov r3, %5;\ mov r4, %6;\ swi 1;\ mov %0, r0;" : "=r"(ret) : "r"(sysid), "r"((intptr_t)(p1)), "r"((intptr_t)(p2)), "r"((intptr_t)(p3)), "r"((intptr_t)(p4)), "r"((intptr_t)(p5)) : "memory", "r0", "r1", "r2", "r3", "r4", "r7"); #elif __aarch64__ asm volatile( "mov x8, %x1;\ mov x0, %x2;\ mov x1, %x3;\ mov x2, %x4;\ mov x3, %x5;\ mov x4, %x6;\ svc 1;\ mov %x0, x0;" : "=r"(ret) : "r"(sysid), "r"((intptr_t)(p1)), "r"((intptr_t)(p2)), "r"((intptr_t)(p3)), "r"((intptr_t)(p4)), "r"((intptr_t)(p5)) : "memory", "x0", "x1", "x2", "x3", "x4", "x8"); #elif defined(__riscv) && (__riscv_xlen == 64) // TODO: Check copatability with Linux. asm volatile( "mv a7, %1;\ mv a0, %2;\ mv a1, %3;\ mv a2, %4;\ mv a3, %5;\ mv a4, %6;\ ecall;\ mv %0, a0;" : "=r"(ret) : "r"(sysid), "r"((intptr_t)(p1)), "r"((intptr_t)(p2)), "r"((intptr_t)(p3)), "r"((intptr_t)(p4)), "r"((intptr_t)(p5)) : "memory", "a0", "a1", "a2", "a3", "a4", "a7"); #endif return ret; } #define DO_SYSCALL_0(type) _syscall_impl(type, 0, 0, 0, 0, 0) #define DO_SYSCALL_1(type, a) _syscall_impl(type, (intptr_t)a, 0, 0, 0, 0) #define DO_SYSCALL_2(type, a, b) _syscall_impl(type, (intptr_t)a, (intptr_t)b, 0, 0, 0) #define DO_SYSCALL_3(type, a, b, c) _syscall_impl(type, (intptr_t)a, (intptr_t)b, (intptr_t)c, 0, 0) #define DO_SYSCALL_4(type, a, b, c, d) _syscall_impl(type, (intptr_t)a, (intptr_t)b, (intptr_t)c, (intptr_t)d, 0) #define DO_SYSCALL_5(type, a, b, c, d, e) _syscall_impl(type, (intptr_t)a, (intptr_t)b, (intptr_t)c, (intptr_t)d, (intptr_t)e); #define RETURN_WITH_ERRNO(res, on_suc, on_fail) \ do { \ if ((intptr_t)res < 0) { \ set_errno(res); \ return (on_fail); \ } \ set_errno(0); \ return on_suc; \ } while (0); __END_DECLS #endif // _LIBC_SYSDEP_H