94 lines
3.3 KiB
C
94 lines
3.3 KiB
C
#ifndef _LIBC_SYSDEP_H
|
|
#define _LIBC_SYSDEP_H
|
|
|
|
#include <bits/syscalls.h>
|
|
#include <errno.h>
|
|
#include <stdint.h>
|
|
#include <sys/cdefs.h>
|
|
|
|
__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
|