#include <sys/syscall.h>
#ifndef SYS_setquota
#define SYS_setquota 148
#endif
#ifndef SYS_quota
#define SYS_quota 149
#endif
#if defined(__ppc__) || defined(__ppc64__)
#include <architecture/ppc/mode_independent_asm.h>
#define kernel_trap_args_0
#define kernel_trap_args_1
#define kernel_trap_args_2
#define kernel_trap_args_3
#define kernel_trap_args_4
#define kernel_trap_args_5
#define kernel_trap_args_6
#define kernel_trap_args_7
#define kernel_trap_args_8
#define SYSCALL(name, nargs) \
.globl cerror @\
MI_ENTRY_POINT(_##name) @\
kernel_trap_args_##nargs @\
li r0,SYS_##name @\
sc @\
b 1f @\
blr @\
1: MI_BRANCH_EXTERNAL(cerror)
#define SYSCALL_NONAME(name, nargs) \
.globl cerror @\
kernel_trap_args_##nargs @\
li r0,SYS_##name @\
sc @\
b 1f @\
b 2f @\
1: MI_BRANCH_EXTERNAL(cerror) @\
2:
#define PSEUDO(pseudo, name, nargs) \
.private_extern _##pseudo @\
.text @\
.align 2 @\
_##pseudo: @\
SYSCALL_NONAME(name, nargs)
#define __SYSCALL(pseudo, name, nargs) \
PSEUDO(pseudo, name, nargs) @\
blr
#elif defined(__i386__)
#include <architecture/i386/asm_help.h>
#include <mach/i386/syscall_sw.h>
#define UNIX_SYSCALL_SYSENTER call __sysenter_trap
#define UNIX_SYSCALL(name, nargs) \
.globl cerror ;\
LEAF(_##name, 0) ;\
movl $ SYS_##name, %eax ;\
UNIX_SYSCALL_SYSENTER ;\
jnb 2f ;\
BRANCH_EXTERN(cerror) ;\
2:
#define UNIX_SYSCALL_INT(name, nargs) \
.globl cerror ;\
LEAF(_##name, 0) ;\
movl $ SYS_##name, %eax ;\
UNIX_SYSCALL_TRAP ;\
jnb 2f ;\
BRANCH_EXTERN(cerror) ;\
2:
#if defined(__SYSCALL_I386_ARG_BYTES) && ((__SYSCALL_I386_ARG_BYTES >= 4) && (__SYSCALL_I386_ARG_BYTES <= 20))
#define UNIX_SYSCALL_NONAME(name, nargs) \
movl $(SYS_##name | (__SYSCALL_I386_ARG_BYTES << I386_SYSCALL_ARG_BYTES_SHIFT)), %eax ;\
UNIX_SYSCALL_SYSENTER ;\
jnb 2f ;\
BRANCH_EXTERN(cerror) ;\
2:
#else
#define UNIX_SYSCALL_NONAME(name, nargs) \
.globl cerror ;\
movl $ SYS_##name, %eax ;\
UNIX_SYSCALL_SYSENTER ;\
jnb 2f ;\
BRANCH_EXTERN(cerror) ;\
2:
#endif
#define UNIX_SYSCALL_INT_NONAME(name, nargs) \
.globl cerror ;\
movl $ SYS_##name, %eax ;\
UNIX_SYSCALL_TRAP ;\
jnb 2f ;\
BRANCH_EXTERN(cerror) ;\
2:
#define PSEUDO(pseudo, name, nargs) \
LEAF(_##pseudo, 0) ;\
UNIX_SYSCALL_NONAME(name, nargs)
#define PSEUDO_INT(pseudo, name, nargs) \
LEAF(_##pseudo, 0) ;\
UNIX_SYSCALL_INT_NONAME(name, nargs)
#define __SYSCALL(pseudo, name, nargs) \
PSEUDO(pseudo, name, nargs) ;\
ret
#define __SYSCALL_INT(pseudo, name, nargs) \
PSEUDO_INT(pseudo, name, nargs) ;\
ret
#elif defined(__x86_64__)
#include <architecture/i386/asm_help.h>
#include <mach/i386/syscall_sw.h>
#define UNIX_SYSCALL_SYSCALL \
movq %rcx, %r10 ;\
syscall
#define UNIX_SYSCALL(name, nargs) \
.globl cerror ;\
LEAF(_##name, 0) ;\
movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\
UNIX_SYSCALL_SYSCALL ;\
jnb 2f ;\
BRANCH_EXTERN(cerror) ;\
2:
#define UNIX_SYSCALL_NONAME(name, nargs) \
.globl cerror ;\
movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\
UNIX_SYSCALL_SYSCALL ;\
jnb 2f ;\
BRANCH_EXTERN(cerror) ;\
2:
#define PSEUDO(pseudo, name, nargs) \
LEAF(_##pseudo, 0) ;\
UNIX_SYSCALL_NONAME(name, nargs)
#define __SYSCALL(pseudo, name, nargs) \
PSEUDO(pseudo, name, nargs) ;\
ret
#elif defined(__arm__)
#define SWI_SYSCALL 0x80 // from <mach/vm_param.h>
#if defined(__DYNAMIC__)
#define MI_GET_ADDRESS(reg,var) \
ldr reg, 4f ;\
3: ldr reg, [pc, reg] ;\
b 5f ;\
4: .long 6f - (3b + 8) ;\
5: ;\
.non_lazy_symbol_pointer ;\
6: ;\
.indirect_symbol var ;\
.long 0 ;\
.text ;\
.align 2
#else
#define MI_GET_ADDRESS(reg,var) \
ldr reg, 3f ;\
b 4f ;\
3: .long var ;\
4:
#endif
#if defined(__DYNAMIC__)
#define MI_BRANCH_EXTERNAL(var) \
.globl var ;\
MI_GET_ADDRESS(ip, var) ;\
bx ip
#else
#define MI_BRANCH_EXTERNAL(var) ;\
.globl var ;\
b var
#endif
#if defined(__DYNAMIC__)
#define MI_CALL_EXTERNAL(var) \
.globl var ;\
MI_GET_ADDRESS(ip,var) ;\
mov lr, pc ;\
bx ip
#else
#define MI_CALL_EXTERNAL(var) \
.globl var ;\
bl var
#endif
#define MI_ENTRY_POINT(name) \
.align 2 ;\
.globl name ;\
.text ;\
name:
#define DO_SYSCALL(num) \
.if (((num) & 0xff) == (num)) ;\
mov r12, #(num) ;\
.elseif (((num) & 0x3fc) == (num)) ;\
mov r12, #(num) ;\
.else ;\
mov r12, #((num) & 0xffffff00) ;\
orr r12, r12, #((num) & 0xff) ;\
.endif ;\
swi #SWI_SYSCALL
#define SYSCALL_0to4(name) \
MI_ENTRY_POINT(_##name) ;\
DO_SYSCALL(SYS_##name) ;\
bxcc lr ; \
1: MI_BRANCH_EXTERNAL(cerror)
#define SYSCALL_5(name) \
MI_ENTRY_POINT(_##name) ;\
mov ip, sp ; \
stmfd sp!, { r4-r5 } ;\
ldr r4, [ip] ; \
DO_SYSCALL(SYS_##name) ;\
ldmfd sp!, { r4-r5 } ; \
bxcc lr ; \
1: MI_BRANCH_EXTERNAL(cerror)
#define SYSCALL_6to8(name, save_regs, arg_regs) \
MI_ENTRY_POINT(_##name) ;\
mov ip, sp ; \
stmfd sp!, { save_regs } ;\
ldmia ip, { arg_regs } ; \
DO_SYSCALL(SYS_##name) ;\
ldmfd sp!, { save_regs } ; \
bxcc lr ; \
1: MI_BRANCH_EXTERNAL(cerror)
#define COMMA ,
#define SYSCALL_0(name) SYSCALL_0to4(name)
#define SYSCALL_1(name) SYSCALL_0to4(name)
#define SYSCALL_2(name) SYSCALL_0to4(name)
#define SYSCALL_3(name) SYSCALL_0to4(name)
#define SYSCALL_4(name) SYSCALL_0to4(name)
#define SYSCALL_6(name) SYSCALL_6to8(name, r4-r5, r4-r5)
#define SYSCALL_7(name) SYSCALL_6to8(name, r4-r6 COMMA r8, r4-r6)
#define SYSCALL_8(name) SYSCALL_6to8(name, r4-r6 COMMA r8, r4-r6 COMMA r8)
#define SYSCALL(name, nargs) SYSCALL_##nargs(name)
#define SYSCALL_NONAME_0to4(name) \
DO_SYSCALL(SYS_##name) ;\
bcc 1f ; \
MI_BRANCH_EXTERNAL(cerror) ; \
1:
#define SYSCALL_NONAME_5(name) \
mov ip, sp ; \
stmfd sp!, { r4-r5 } ;\
ldr r4, [ip] ; \
DO_SYSCALL(SYS_##name) ;\
ldmfd sp!, { r4-r5 } ; \
bcc 1f ; \
MI_BRANCH_EXTERNAL(cerror) ; \
1:
#define SYSCALL_NONAME_6to8(name, save_regs, arg_regs) \
mov ip, sp ; \
stmfd sp!, { save_regs } ;\
ldmia ip, { arg_regs } ; \
DO_SYSCALL(SYS_##name) ;\
ldmfd sp!, { save_regs } ; \
bcc 1f ; \
MI_BRANCH_EXTERNAL(cerror) ; \
1:
#define SYSCALL_NONAME_0(name) SYSCALL_NONAME_0to4(name)
#define SYSCALL_NONAME_1(name) SYSCALL_NONAME_0to4(name)
#define SYSCALL_NONAME_2(name) SYSCALL_NONAME_0to4(name)
#define SYSCALL_NONAME_3(name) SYSCALL_NONAME_0to4(name)
#define SYSCALL_NONAME_4(name) SYSCALL_NONAME_0to4(name)
#define SYSCALL_NONAME_6(name) SYSCALL_NONAME_6to8(name, r4-r5, r4-r5)
#define SYSCALL_NONAME_7(name) SYSCALL_NONAME_6to8(name, r4-r6 COMMA r8, r4-r6)
#define SYSCALL_NONAME_8(name) SYSCALL_NONAME_6to8(name, r4-r6 COMMA r8, r4-r6 COMMA r8)
#define SYSCALL_NONAME(name, nargs) SYSCALL_NONAME_##nargs(name)
#define PSEUDO(pseudo, name, nargs) \
.globl _##pseudo ;\
.text ;\
.align 2 ;\
_##pseudo: ;\
SYSCALL_NONAME(name, nargs)
#define __SYSCALL(pseudo, name, nargs) \
PSEUDO(pseudo, name, nargs) ;\
bx lr
#else
#error Unsupported architecture
#endif