aboutsummaryrefslogtreecommitdiff
path: root/lib/darwin/manual-syscall.h
blob: 91f600b4d626d38c4109ac37773719b525c8fda8 (plain) (blame)
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
#pragma once

#define GEN_SYSCALL(name, num) \
    __asm__(".private_extern _manual_" #name "\n" \
            ".pushsection __TEXT,__text,regular,pure_instructions\n" \
            GEN_SYSCALL_PRE(name) \
            "_manual_" #name ":\n" \
            ".set num, " #num "\n" \
            GEN_SYSCALL_INNER() \
            ".popsection\n")
#define GEN_SYSCALL_PRE(name)

#if defined(__x86_64__)
/* Look at me, I'm different! */
#define GEN_SYSCALL_INNER() \
    ".if num < 0\n" \
        "mov $(-num | 1 << 24), %eax\n" \
    ".else\n" \
        "mov $( num | 2 << 24), %eax\n" \
    ".endif\n" \
    "mov %rcx, %r10\n" \
    "syscall\n" \
    "ret\n"

#elif defined(__i386__)
#define GEN_SYSCALL_INNER() \
    "mov $num, %eax\n" \
    "call 0f\n" \
    "0: pop %edx\n" \
    "add $(1f-0b), %edx\n" \
    "mov %esp, %ecx\n" \
    "sysenter\n" \
    "1: ret\n"
#elif defined(__arm__)
#ifdef __thumb__
#undef GEN_SYSCALL_PRE
#define GEN_SYSCALL_PRE(name) \
    ".thumb_func _manual_" #name "\n" \
    ".align 2\n"
#endif
#define GEN_SYSCALL_INNER() \
    "mov r12, sp\n" \
    "push {r4-r6}\n" \
    "ldm r12, {r4-r6}\n" \
    "mov r12, #num\n" \
    "svc #0x80\n" \
    "pop {r4-r6}\n" \
    "bx lr\n"
#elif defined(__arm64__)
#define GEN_SYSCALL_INNER() \
    "mov x16, #num\n" \
    "svc #0x80\n" \
    "ret\n"
#else
#error ?
#endif