X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b0d623f7f2ae71ed96e60569f61f9a9a27016e80..eb6b6ca394357805f2bdba989abae309f718b4d8:/libsyscall/custom/SYS.h?ds=sidebyside diff --git a/libsyscall/custom/SYS.h b/libsyscall/custom/SYS.h index a4eb976a2..ffc6a8f2e 100644 --- a/libsyscall/custom/SYS.h +++ b/libsyscall/custom/SYS.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * Copyright (c) 1999-2011 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -48,53 +48,7 @@ #include -#ifndef SYS_setquota -#define SYS_setquota 148 -#endif -#ifndef SYS_quota -#define SYS_quota 149 -#endif - -#if defined(__ppc__) || defined(__ppc64__) - -#include - -/* - * Macros. - */ - -#define SYSCALL(name, nargs) \ - .globl cerror @\ - MI_ENTRY_POINT(_##name) @\ - li r0,SYS_##name @\ - sc @\ - b 1f @\ - blr @\ -1: MI_BRANCH_EXTERNAL(cerror) - - -#define SYSCALL_NONAME(name, nargs) \ - .globl cerror @\ - 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__) +#if defined(__i386__) #include #include @@ -107,58 +61,61 @@ _##pseudo: @\ #define UNIX_SYSCALL_SYSENTER call __sysenter_trap #define UNIX_SYSCALL(name, nargs) \ - .globl cerror ;\ + .globl tramp_cerror ;\ LEAF(_##name, 0) ;\ movl $ SYS_##name, %eax ;\ UNIX_SYSCALL_SYSENTER ;\ jnb 2f ;\ - BRANCH_EXTERN(cerror) ;\ + BRANCH_EXTERN(tramp_cerror) ;\ 2: #define UNIX_SYSCALL_INT(name, nargs) \ - .globl cerror ;\ + .globl tramp_cerror ;\ LEAF(_##name, 0) ;\ movl $ SYS_##name, %eax ;\ UNIX_SYSCALL_TRAP ;\ jnb 2f ;\ - BRANCH_EXTERN(cerror) ;\ + BRANCH_EXTERN(tramp_cerror) ;\ 2: #if defined(__SYSCALL_32BIT_ARG_BYTES) && ((__SYSCALL_32BIT_ARG_BYTES >= 4) && (__SYSCALL_32BIT_ARG_BYTES <= 20)) -#define UNIX_SYSCALL_NONAME(name, nargs) \ +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ movl $(SYS_##name | (__SYSCALL_32BIT_ARG_BYTES << I386_SYSCALL_ARG_BYTES_SHIFT)), %eax ;\ UNIX_SYSCALL_SYSENTER ;\ jnb 2f ;\ - BRANCH_EXTERN(cerror) ;\ + BRANCH_EXTERN(tramp_##cerror) ;\ 2: #else /* __SYSCALL_32BIT_ARG_BYTES < 4 || > 20 */ -#define UNIX_SYSCALL_NONAME(name, nargs) \ - .globl cerror ;\ +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ movl $ SYS_##name, %eax ;\ UNIX_SYSCALL_SYSENTER ;\ jnb 2f ;\ - BRANCH_EXTERN(cerror) ;\ + BRANCH_EXTERN(tramp_##cerror) ;\ 2: #endif #define UNIX_SYSCALL_INT_NONAME(name, nargs) \ - .globl cerror ;\ + .globl tramp_cerror_nocancel ;\ movl $ SYS_##name, %eax ;\ UNIX_SYSCALL_TRAP ;\ jnb 2f ;\ - BRANCH_EXTERN(cerror) ;\ + BRANCH_EXTERN(tramp_cerror_nocancel) ;\ 2: -#define PSEUDO(pseudo, name, nargs) \ -LEAF(_##pseudo, 0) ;\ - UNIX_SYSCALL_NONAME(name, nargs) +#define PSEUDO(pseudo, name, nargs, cerror) \ +LEAF(pseudo, 0) ;\ + UNIX_SYSCALL_NONAME(name, nargs, cerror) -#define PSEUDO_INT(pseudo, name, nargs) \ -LEAF(_##pseudo, 0) ;\ +#define PSEUDO_INT(pseudo, name, nargs) \ +LEAF(pseudo, 0) ;\ UNIX_SYSCALL_INT_NONAME(name, nargs) +#define __SYSCALL2(pseudo, name, nargs, cerror) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret + #define __SYSCALL(pseudo, name, nargs) \ - PSEUDO(pseudo, name, nargs) ;\ + PSEUDO(pseudo, name, nargs, cerror) ;\ ret #define __SYSCALL_INT(pseudo, name, nargs) \ @@ -174,31 +131,362 @@ LEAF(_##pseudo, 0) ;\ 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) ;\ +#define UNIX_SYSCALL(name, nargs) \ + .globl cerror ;\ +LEAF(_##name, 0) ;\ + movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ + UNIX_SYSCALL_SYSCALL ;\ + jnb 2f ;\ + movq %rax, %rdi ;\ + 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) ;\ +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ + .globl cerror ;\ + movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ + UNIX_SYSCALL_SYSCALL ;\ + jnb 2f ;\ + movq %rax, %rdi ;\ + BRANCH_EXTERN(_##cerror) ;\ 2: -#define PSEUDO(pseudo, name, nargs) \ -LEAF(_##pseudo, 0) ;\ - UNIX_SYSCALL_NONAME(name, nargs) +#define PSEUDO(pseudo, name, nargs, cerror) \ +LEAF(pseudo, 0) ;\ + UNIX_SYSCALL_NONAME(name, nargs, cerror) + +#define __SYSCALL2(pseudo, name, nargs, cerror) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret #define __SYSCALL(pseudo, name, nargs) \ - PSEUDO(pseudo, name, nargs) ;\ + PSEUDO(pseudo, name, nargs, cerror) ;\ ret +#elif defined(__arm__) + +#include +#include + +/* + * ARM system call interface: + * + * swi 0x80 + * args: r0-r6 + * return code: r0 + * on error, carry bit is set in the psr, otherwise carry bit is cleared. + */ + +/* + * Macros. + */ + +/* + * until we update the architecture project, these live here + */ + +#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) ;\ + blx ip +#else +#define MI_CALL_EXTERNAL(var) \ + .globl var ;\ + bl var +#endif + +#define MI_ENTRY_POINT(name) \ + .text ;\ + .align 2 ;\ + .globl name ;\ +name: + +/* load the syscall number into r12 and trap */ +#define DO_SYSCALL(num) \ + .if (((num) & 0xff) == (num)) ;\ + mov r12, #(num) ;\ + .elseif (((num) & 0x3fc) == (num)) ;\ + mov r12, #(num) ;\ + .else ;\ + mov r12, #((num) & 0xffffff00) /* top half of the syscall number */ ;\ + orr r12, r12, #((num) & 0xff) /* bottom half */ ;\ + .endif ;\ + swi #SWI_SYSCALL + +/* simple syscalls (0 to 4 args) */ +#define SYSCALL_0to4(name, cerror) \ + MI_ENTRY_POINT(_##name) ;\ + DO_SYSCALL(SYS_##name) ;\ + bxcc lr /* return if carry is clear (no error) */ ; \ +1: MI_BRANCH_EXTERNAL(_##cerror) + +/* syscalls with 5 args is different, because of the single arg register load */ +#define SYSCALL_5(name, cerror) \ + MI_ENTRY_POINT(_##name) ;\ + mov ip, sp /* save a pointer to the args */ ; \ + stmfd sp!, { r4-r5 } /* save r4-r5 */ ;\ + ldr r4, [ip] /* load 5th arg */ ; \ + DO_SYSCALL(SYS_##name) ;\ + ldmfd sp!, { r4-r5 } /* restore r4-r5 */ ; \ + bxcc lr /* return if carry is clear (no error) */ ; \ +1: MI_BRANCH_EXTERNAL(_##cerror) + +/* syscalls with 6 to 12 args. kernel may have to read from stack */ +#define SYSCALL_6to12(name, save_regs, arg_regs, cerror) \ + MI_ENTRY_POINT(_##name) ;\ + mov ip, sp /* save a pointer to the args */ ; \ + stmfd sp!, { save_regs } /* callee saved regs */ ;\ + ldmia ip, { arg_regs } /* load arg regs */ ; \ + DO_SYSCALL(SYS_##name) ;\ + ldmfd sp!, { save_regs } /* restore callee saved regs */ ; \ + bxcc lr /* return if carry is clear (no error) */ ; \ +1: MI_BRANCH_EXTERNAL(_##cerror) + +#define COMMA , + +#if __BIGGEST_ALIGNMENT__ > 4 + +/* For the armv7k ABI, the alignment requirements may add padding. So we + * let the kernel figure it out and push extra on the stack to avoid un-needed + * copy-ins */ + + /* We'll also use r8 for moving arguments */ + +#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_6to12(name, r4-r5, r4-r5) +#undef SYSCALL_5 +#define SYSCALL_5(name) SYSCALL_6to12(name, r4-r5, r4-r5) +#define SYSCALL_6(name) SYSCALL_6to12(name, r4-r6 COMMA r8, r4-r6 COMMA r8) +#define SYSCALL_7(name) SYSCALL_6to12(name, r4-r6 COMMA r8, r4-r6 COMMA r8) +#define SYSCALL_8(name) SYSCALL_6to12(name, r4-r6 COMMA r8, r4-r6 COMMA r8) +#define SYSCALL_12(name) SYSCALL_6to12(name, r4-r6 COMMA r8, r4-r6 COMMA r8) + +#else // !(__BIGGEST_ALIGNMENT__ > 4) (the normal arm32 ABI case) + +#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) +/* SYSCALL_5 declared above */ +#define SYSCALL_6(name) SYSCALL_6to12(name, r4-r5, r4-r5) +#define SYSCALL_7(name) SYSCALL_6to12(name, r4-r6 COMMA r8, r4-r6) +#define SYSCALL_8(name) SYSCALL_6to12(name, r4-r6 COMMA r8, r4-r6) /* 8th on stack */ +#define SYSCALL_12(name) SYSCALL_6to12(name, r4-r6 COMMA r8, r4-r6) /* 8th-12th on stack */ + +#endif // __BIGGEST_ALIGNMENT__ > 4 + +/* select the appropriate syscall code, based on the number of arguments */ +#ifndef __SYSCALL_32BIT_ARG_BYTES +#define SYSCALL(name, nargs, cerror) SYSCALL_##nargs(name, cerror) +#define SYSCALL_NONAME(name, nargs, cerror) SYSCALL_NONAME_##nargs(name, cerror) +#else +#if __SYSCALL_32BIT_ARG_BYTES < 20 +#define SYSCALL(name, nargs, cerror) SYSCALL_0to4(name, cerror) +#define SYSCALL_NONAME(name, nargs, cerror) SYSCALL_NONAME_0to4(name, cerror) +#elif __SYSCALL_32BIT_ARG_BYTES == 20 +#define SYSCALL(name, nargs, cerror) SYSCALL_5(name, cerror) +#define SYSCALL_NONAME(name, nargs, cerror) SYSCALL_NONAME_5(name, cerror) +#elif __SYSCALL_32BIT_ARG_BYTES == 24 +#define SYSCALL(name, nargs, cerror) SYSCALL_6(name, cerror) +#define SYSCALL_NONAME(name, nargs, cerror) SYSCALL_NONAME_6(name, cerror) +#elif __SYSCALL_32BIT_ARG_BYTES == 28 +#define SYSCALL(name, nargs, cerror) SYSCALL_7(name, cerror) +#define SYSCALL_NONAME(name, nargs, cerror) SYSCALL_NONAME_7(name, cerror) +#elif __SYSCALL_32BIT_ARG_BYTES == 32 +#define SYSCALL(name, nargs, cerror) SYSCALL_8(name, cerror) +#define SYSCALL_NONAME(name, nargs, cerror) SYSCALL_NONAME_8(name, cerror) +#elif __SYSCALL_32BIT_ARG_BYTES == 36 +#define SYSCALL(name, nargs, cerror) SYSCALL_8(name, cerror) +#define SYSCALL_NONAME(name, nargs, cerror) SYSCALL_NONAME_8(name, cerror) +#elif __SYSCALL_32BIT_ARG_BYTES == 44 +#define SYSCALL(name, nargs, cerror) SYSCALL_8(name, cerror) +#define SYSCALL_NONAME(name, nargs, cerror) SYSCALL_NONAME_8(name, cerror) +#elif __SYSCALL_32BIT_ARG_BYTES == 48 +#define SYSCALL(name, nargs, cerror) SYSCALL_12(name, cerror) +#define SYSCALL_NONAME(name, nargs, cerror) SYSCALL_NONAME_12(name, cerror) +#endif +#endif + +#define SYSCALL_NONAME_0to4(name, cerror) \ + DO_SYSCALL(SYS_##name) ;\ + bcc 1f /* branch if carry bit is clear (no error) */ ; \ + MI_BRANCH_EXTERNAL(_##cerror) /* call cerror */ ; \ +1: + +#define SYSCALL_NONAME_5(name, cerror) \ + mov ip, sp /* save a pointer to the args */ ; \ + stmfd sp!, { r4-r5 } /* save r4-r5 */ ;\ + ldr r4, [ip] /* load 5th arg */ ; \ + DO_SYSCALL(SYS_##name) ;\ + ldmfd sp!, { r4-r5 } /* restore r4-r7 */ ; \ + bcc 1f /* branch if carry bit is clear (no error) */ ; \ + MI_BRANCH_EXTERNAL(_##cerror) /* call cerror */ ; \ +1: + +#define SYSCALL_NONAME_6to12(name, save_regs, arg_regs, cerror) \ + mov ip, sp /* save a pointer to the args */ ; \ + stmfd sp!, { save_regs } /* callee save regs */ ;\ + ldmia ip, { arg_regs } /* load arguments */ ; \ + DO_SYSCALL(SYS_##name) ;\ + ldmfd sp!, { save_regs } /* restore callee saved regs */ ; \ + bcc 1f /* branch if carry bit is clear (no error) */ ; \ + MI_BRANCH_EXTERNAL(_##cerror) /* call cerror */ ; \ +1: + + +#if __BIGGEST_ALIGNMENT__ > 4 + +/* For the armv7k ABI, the alignment requirements may add padding. So we + * let the kernel figure it out and push extra on the stack to avoid un-needed + * copy-ins. We are relying on arguments that aren't in registers starting + * 32 bytes from sp. We also use r8 like in the mach case. */ + +#define SYSCALL_NONAME_0(name, cerror) SYSCALL_NONAME_0to4(name, cerror) +#define SYSCALL_NONAME_1(name, cerror) SYSCALL_NONAME_0to4(name, cerror) +#define SYSCALL_NONAME_2(name, cerror) SYSCALL_NONAME_0to4(name, cerror) +#define SYSCALL_NONAME_3(name, cerror) SYSCALL_NONAME_0to4(name, cerror) +#define SYSCALL_NONAME_4(name, cerror) SYSCALL_NONAME_6to12(name, r4-r5, r4-r5, cerror) +#undef SYSCALL_NONAME_5 +#define SYSCALL_NONAME_5(name, cerror) SYSCALL_NONAME_6to12(name, r4-r5, r4-r5, cerror) +#define SYSCALL_NONAME_6(name, cerror) SYSCALL_NONAME_6to12(name, r4-r6 COMMA r8, r4-r6 COMMA r8, cerror) +#define SYSCALL_NONAME_7(name, cerror) SYSCALL_NONAME_6to12(name, r4-r6 COMMA r8, r4-r6 COMMA r8, cerror) +#define SYSCALL_NONAME_8(name, cerror) SYSCALL_NONAME_6to12(name, r4-r6 COMMA r8, r4-r6 COMMA r8, cerror) +#define SYSCALL_NONAME_12(name, cerror) SYSCALL_NONAME_6to12(name, r4-r6 COMMA r8, r4-r6 COMMA r8, cerror) + +#else // !(__BIGGEST_ALIGNMENT__ > 4) (the normal arm32 ABI case) + +#define SYSCALL_NONAME_0(name, cerror) SYSCALL_NONAME_0to4(name, cerror) +#define SYSCALL_NONAME_1(name, cerror) SYSCALL_NONAME_0to4(name, cerror) +#define SYSCALL_NONAME_2(name, cerror) SYSCALL_NONAME_0to4(name, cerror) +#define SYSCALL_NONAME_3(name, cerror) SYSCALL_NONAME_0to4(name, cerror) +#define SYSCALL_NONAME_4(name, cerror) SYSCALL_NONAME_0to4(name, cerror) +/* SYSCALL_NONAME_5 declared above */ +#define SYSCALL_NONAME_6(name, cerror) SYSCALL_NONAME_6to12(name, r4-r5, r4-r5, cerror) +#define SYSCALL_NONAME_7(name, cerror) SYSCALL_NONAME_6to12(name, r4-r6 COMMA r8, r4-r6, cerror) +#define SYSCALL_NONAME_8(name, cerror) SYSCALL_NONAME_6to12(name, r4-r6 COMMA r8, r4-r6, cerror) +#define SYSCALL_NONAME_12(name, cerror) SYSCALL_NONAME_6to12(name, r4-r6 COMMA r8, r4-r6, cerror) + +#endif // __BIGGEST_ALIGNMENT__ > 4 + +#define PSEUDO(pseudo, name, nargs, cerror) \ + .globl pseudo ;\ + .text ;\ + .align 2 ;\ +pseudo: ;\ + SYSCALL_NONAME(name, nargs, cerror) + +#define __SYSCALL2(pseudo, name, nargs, cerror) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + bx lr + +#define __SYSCALL(pseudo, name, nargs) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + bx lr + +#elif defined(__arm64__) + +#include +#include +#include + +#if defined(__arm64__) && !defined(__LP64__) +#define ZERO_EXTEND(argnum) uxtw x ## argnum, w ## argnum +#else +#define ZERO_EXTEND(argnum) +#endif + +#if defined(__arm64__) && !defined(__LP64__) +#define SIGN_EXTEND(argnum) sxtw x ## argnum, w ## argnum +#else +#define SIGN_EXTEND(argnum) +#endif + +/* + * ARM64 system call interface: + * + * TBD + */ + +#define DO_SYSCALL(num, cerror) \ + mov x16, #(num) %%\ + svc #SWI_SYSCALL %%\ + b.cc 2f %%\ + PUSH_FRAME %%\ + bl _##cerror %%\ + POP_FRAME %%\ + ret %%\ +2: + +#define MI_GET_ADDRESS(reg,var) \ + adrp reg, var@page %%\ + add reg, reg, var@pageoff %% + +#define MI_CALL_EXTERNAL(sym) \ + .globl sym %% \ + bl sym + +#define SYSCALL_NONAME(name, nargs, cerror) \ + DO_SYSCALL(SYS_##name, cerror) %% \ +1: + +#define MI_ENTRY_POINT(name) \ + .text %% \ + .align 2 %% \ + .globl name %% \ +name: + +#define PSEUDO(pseudo, name, nargs, cerror) \ + .text %% \ + .align 2 %% \ + .globl pseudo %% \ + pseudo: %% \ + SYSCALL_NONAME(name, nargs, cerror) + +#define __SYSCALL(pseudo, name, nargs) \ + PSEUDO(pseudo, name, nargs, cerror) %% \ + ret + +#define __SYSCALL2(pseudo, name, nargs, cerror) \ + PSEUDO(pseudo, name, nargs, cerror) %% \ + ret + #else #error Unsupported architecture #endif +