diff options
Diffstat (limited to 'lib/darwin/manual-syscall.h')
-rw-r--r-- | lib/darwin/manual-syscall.h | 75 |
1 files changed, 31 insertions, 44 deletions
diff --git a/lib/darwin/manual-syscall.h b/lib/darwin/manual-syscall.h index 9f04d2b..b1bac7e 100644 --- a/lib/darwin/manual-syscall.h +++ b/lib/darwin/manual-syscall.h @@ -1,54 +1,41 @@ #pragma once -#define REG(var, reg) register long _##var __asm__(#reg) = var -#define OREG(var, reg) register long var __asm__(#reg) +#define GEN_SYSCALL(name, num) \ + __asm__(".globl _manual_" #name "\n" \ + ".pushsection __TEXT,__text,regular,pure_instructions\n" \ + "_manual_" #name ":\n" \ + ".set num, " #num "\n" \ + GEN_SYSCALL_INNER() \ + ".popsection\n") -__attribute__((always_inline)) #if defined(__x86_64__) -static int manual_syscall(long s, long a, long b, long c, long d) { - if (s < 0) - s = -s | 1 << 24; - else - s |= 2 << 24; - REG(s, rax); REG(a, rdi); REG(b, rsi); REG(c, rdx); REG(d, rcx); - OREG(out, rax); - __asm__ volatile("syscall" - : "=r"(out) - : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); - return out; -} +/* 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__) -static int manual_syscall(long s, long a, long b, long c, long d) { - REG(s, eax); - OREG(out, eax); - __asm__ volatile("push %5; push %4; push %3; push %2; push $0;" - "mov %%esp, %%ecx;" - "call 1f; 1: pop %%edx; add $(2f-1b), %%edx;" - "sysenter;" - "2: add $(5 * 4), %%esp" - : "=r"(out) - : "r"(_s), "g"(a), "g"(b), "g"(c), "g"(d) - : "edx", "ecx"); - return out; -} +#define GEN_SYSCALL_INNER() \ + "mov $num, %eax\n" \ + "pop %edx\n" \ + "mov %esp, %ecx\n" \ + "sysenter\n" #elif defined(__arm__) -static int manual_syscall(long s, long a, long b, long c, long d) { - REG(s, r12); REG(a, r0); REG(b, r1); REG(c, r2); REG(d, r3); - OREG(out, r0); - __asm__ volatile("svc #0x80" - : "=r"(out) - : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); - return out; -} +#define GEN_SYSCALL_INNER() \ + "mov r12, #num\n" \ + "svc #0x80\n" \ + "bx lr\n" #elif defined(__arm64__) -static int manual_syscall(long s, long a, long b, long c, long d) { - REG(s, x16); REG(a, x0); REG(b, x1); REG(c, x2); REG(d, x3); - OREG(out, x0); - __asm__ volatile("svc #0x80" - : "=r"(out) - : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); - return out; -} +#define GEN_SYSCALL_INNER() \ + "mov x12, #num\n" \ + "svc #0x80\n" \ + "ret\n" #else #error ? #endif |