From 021c39d7a3361290d9e29497cf2a4a8fd2ee7b5c Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Thu, 7 Jun 2018 12:19:42 +0200 Subject: [PATCH] runtime: use libc for signal functions on iOS Also: - Add extra SystemStack space for darwin/arm64 just like for darwin/arm. - Removed redundant stack alignment; the arm64 hardware enforces the 16 byte alignment. - Save and restore the g registers at library initialization. - Zero g registers since libpreinit can call libc functions that in turn use asmcgocall. asmcgocall requires an initialized g. - Change asmcgocall to work even if no g is set. The change mimics amd64. Change-Id: I1b8c63b07cfec23b909c0d215b50dc229f8adbc8 Reviewed-on: https://go-review.googlesource.com/117176 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/vet/all/whitelist/darwin_arm.txt | 6 - src/cmd/vet/all/whitelist/darwin_arm64.txt | 2 - src/runtime/asm_arm.s | 71 ++++++--- src/runtime/asm_arm64.s | 34 ++++- src/runtime/rt0_darwin_arm64.s | 37 +++-- src/runtime/stack.go | 4 +- src/runtime/sys_darwin_arm.s | 147 +++++++++---------- src/runtime/sys_darwin_arm64.s | 163 +++++++++++---------- 8 files changed, 261 insertions(+), 203 deletions(-) diff --git a/src/cmd/vet/all/whitelist/darwin_arm.txt b/src/cmd/vet/all/whitelist/darwin_arm.txt index 8e935b6ff2d..1c25c6a9397 100644 --- a/src/cmd/vet/all/whitelist/darwin_arm.txt +++ b/src/cmd/vet/all/whitelist/darwin_arm.txt @@ -1,11 +1,5 @@ // darwin/arm-specific vet whitelist. See readme.txt for details. -// False positives due to comments in assembly. -// To be removed. See CL 27154. - -runtime/sys_darwin_arm.s: [arm] sigfwd: use of unnamed argument 0(FP); offset 0 is fn+0(FP) - - // Ok. runtime/asm_arm.s: [arm] sigreturn: function sigreturn missing Go declaration diff --git a/src/cmd/vet/all/whitelist/darwin_arm64.txt b/src/cmd/vet/all/whitelist/darwin_arm64.txt index 8cab997961a..a1edb713832 100644 --- a/src/cmd/vet/all/whitelist/darwin_arm64.txt +++ b/src/cmd/vet/all/whitelist/darwin_arm64.txt @@ -1,5 +1,3 @@ // darwin/arm64-specific vet whitelist. See readme.txt for details. -runtime/sys_darwin_arm64.s: [arm64] sigtramp: 24(RSP) should be infostyle+8(FP) -runtime/sys_darwin_arm64.s: [arm64] sigtramp: 24(RSP) should be infostyle+8(FP) runtime/asm_arm64.s: [arm64] sigreturn: function sigreturn missing Go declaration diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s index 545e58e9b04..6722ba760fb 100644 --- a/src/runtime/asm_arm.s +++ b/src/runtime/asm_arm.s @@ -36,25 +36,28 @@ TEXT _rt0_arm_lib(SB),NOSPLIT,$104 MOVW R6, 20(R13) MOVW R7, 24(R13) MOVW R8, 28(R13) - MOVW R11, 32(R13) + MOVW g, 32(R13) + MOVW R11, 36(R13) // Skip floating point registers on GOARM < 6. MOVB runtime·goarm(SB), R11 CMP $6, R11 BLT skipfpsave - MOVD F8, (32+8*1)(R13) - MOVD F9, (32+8*2)(R13) - MOVD F10, (32+8*3)(R13) - MOVD F11, (32+8*4)(R13) - MOVD F12, (32+8*5)(R13) - MOVD F13, (32+8*6)(R13) - MOVD F14, (32+8*7)(R13) - MOVD F15, (32+8*8)(R13) + MOVD F8, (40+8*0)(R13) + MOVD F9, (40+8*1)(R13) + MOVD F10, (40+8*2)(R13) + MOVD F11, (40+8*3)(R13) + MOVD F12, (40+8*4)(R13) + MOVD F13, (40+8*5)(R13) + MOVD F14, (40+8*6)(R13) + MOVD F15, (40+8*7)(R13) skipfpsave: // Save argc/argv. MOVW R0, _rt0_arm_lib_argc<>(SB) MOVW R1, _rt0_arm_lib_argv<>(SB) + MOVW $0, g // Initialize g. + // Synchronous initialization. CALL runtime·libpreinit(SB) @@ -77,21 +80,22 @@ rr: MOVB runtime·goarm(SB), R11 CMP $6, R11 BLT skipfprest - MOVD (32+8*1)(R13), F8 - MOVD (32+8*2)(R13), F9 - MOVD (32+8*3)(R13), F10 - MOVD (32+8*4)(R13), F11 - MOVD (32+8*5)(R13), F12 - MOVD (32+8*6)(R13), F13 - MOVD (32+8*7)(R13), F14 - MOVD (32+8*8)(R13), F15 + MOVD (40+8*0)(R13), F8 + MOVD (40+8*1)(R13), F9 + MOVD (40+8*2)(R13), F10 + MOVD (40+8*3)(R13), F11 + MOVD (40+8*4)(R13), F12 + MOVD (40+8*5)(R13), F13 + MOVD (40+8*6)(R13), F14 + MOVD (40+8*7)(R13), F15 skipfprest: MOVW 12(R13), R4 MOVW 16(R13), R5 MOVW 20(R13), R6 MOVW 24(R13), R7 MOVW 28(R13), R8 - MOVW 32(R13), R11 + MOVW 32(R13), g + MOVW 36(R13), R11 RET // _rt0_arm_lib_go initializes the Go runtime. @@ -582,6 +586,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12 MOVW arg+4(FP), R0 MOVW R13, R2 + CMP $0, g + BEQ nosave MOVW g, R4 // Figure out if we need to switch to m->g0 stack. @@ -590,10 +596,10 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12 MOVW g_m(g), R8 MOVW m_gsignal(R8), R3 CMP R3, g - BEQ noswitch + BEQ nosave MOVW m_g0(R8), R3 CMP R3, g - BEQ noswitch + BEQ nosave BL gosave<>(SB) MOVW R0, R5 MOVW R3, R0 @@ -602,7 +608,6 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12 MOVW (g_sched+gobuf_sp)(g), R13 // Now on a scheduling stack (a pthread-created stack). -noswitch: SUB $24, R13 BIC $0x7, R13 // alignment for gcc ABI MOVW R4, 20(R13) // save old g @@ -624,6 +629,30 @@ noswitch: MOVW R0, ret+8(FP) RET +nosave: + // Running on a system stack, perhaps even without a g. + // Having no g can happen during thread creation or thread teardown + // (see needm/dropm on Solaris, for example). + // This code is like the above sequence but without saving/restoring g + // and without worrying about the stack moving out from under us + // (because we're on a system stack, not a goroutine stack). + // The above code could be used directly if already on a system stack, + // but then the only path through this code would be a rare case on Solaris. + // Using this code for all "already on system stack" calls exercises it more, + // which should help keep it correct. + SUB $24, R13 + BIC $0x7, R13 // alignment for gcc ABI + // save null g in case someone looks during debugging. + MOVW $0, R4 + MOVW R4, 20(R13) + MOVW R2, 16(R13) // Save old stack pointer. + BL (R1) + // Restore stack pointer. + MOVW 16(R13), R2 + MOVW R2, R13 + MOVW R0, ret+8(FP) + RET + // cgocallback(void (*fn)(void*), void *frame, uintptr framesize, uintptr ctxt) // Turn the fn into a Go func (by taking its address) and call // cgocallback_gofunc. diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s index d1b90b056c9..af389be9fee 100644 --- a/src/runtime/asm_arm64.s +++ b/src/runtime/asm_arm64.s @@ -863,6 +863,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20 MOVD arg+8(FP), R0 MOVD RSP, R2 // save original stack pointer + CMP $0, g + BEQ nosave MOVD g, R4 // Figure out if we need to switch to m->g0 stack. @@ -871,10 +873,12 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20 MOVD g_m(g), R8 MOVD m_gsignal(R8), R3 CMP R3, g - BEQ noswitch + BEQ nosave MOVD m_g0(R8), R3 CMP R3, g - BEQ noswitch + BEQ nosave + + // Switch to system stack. MOVD R0, R9 // gosave<> and save_g might clobber R0 BL gosave<>(SB) MOVD R3, g @@ -884,12 +888,10 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20 MOVD R9, R0 // Now on a scheduling stack (a pthread-created stack). -noswitch: // Save room for two of our pointers /*, plus 32 bytes of callee // save area that lives on the caller stack. */ MOVD RSP, R13 SUB $16, R13 - BIC $0xf, R13 // alignment for gcc ABI MOVD R13, RSP MOVD R4, 0(RSP) // save old g on stack MOVD (g_stack+stack_hi)(R4), R4 @@ -910,6 +912,30 @@ noswitch: MOVW R0, ret+16(FP) RET +nosave: + // Running on a system stack, perhaps even without a g. + // Having no g can happen during thread creation or thread teardown + // (see needm/dropm on Solaris, for example). + // This code is like the above sequence but without saving/restoring g + // and without worrying about the stack moving out from under us + // (because we're on a system stack, not a goroutine stack). + // The above code could be used directly if already on a system stack, + // but then the only path through this code would be a rare case on Solaris. + // Using this code for all "already on system stack" calls exercises it more, + // which should help keep it correct. + MOVD RSP, R13 + SUB $16, R13 + MOVD R13, RSP + MOVD $0, R4 + MOVD R4, 0(RSP) // Where above code stores g, in case someone looks during debugging. + MOVD R2, 8(RSP) // Save original stack pointer. + BL (R1) + // Restore stack pointer. + MOVD 8(RSP), R2 + MOVD R2, RSP + MOVD R0, ret+16(FP) + RET + // cgocallback(void (*fn)(void*), void *frame, uintptr framesize, uintptr ctxt) // Turn the fn into a Go func (by taking its address) and call // cgocallback_gofunc. diff --git a/src/runtime/rt0_darwin_arm64.s b/src/runtime/rt0_darwin_arm64.s index 719944e6265..d039a8e0aba 100644 --- a/src/runtime/rt0_darwin_arm64.s +++ b/src/runtime/rt0_darwin_arm64.s @@ -26,18 +26,21 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$168 MOVD R25, 72(RSP) MOVD R26, 80(RSP) MOVD R27, 88(RSP) - FMOVD F8, 96(RSP) - FMOVD F9, 104(RSP) - FMOVD F10, 112(RSP) - FMOVD F11, 120(RSP) - FMOVD F12, 128(RSP) - FMOVD F13, 136(RSP) - FMOVD F14, 144(RSP) - FMOVD F15, 152(RSP) + MOVD g, 96(RSP) + FMOVD F8, 104(RSP) + FMOVD F9, 112(RSP) + FMOVD F10, 120(RSP) + FMOVD F11, 128(RSP) + FMOVD F12, 136(RSP) + FMOVD F13, 144(RSP) + FMOVD F14, 152(RSP) + FMOVD F15, 160(RSP) MOVD R0, _rt0_arm64_darwin_lib_argc<>(SB) MOVD R1, _rt0_arm64_darwin_lib_argv<>(SB) + MOVD $0, g // initialize g to nil + // Synchronous initialization. MOVD $runtime·libpreinit(SB), R4 BL (R4) @@ -58,14 +61,16 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$168 MOVD 72(RSP), R25 MOVD 80(RSP), R26 MOVD 88(RSP), R27 - FMOVD 96(RSP), F8 - FMOVD 104(RSP), F9 - FMOVD 112(RSP), F10 - FMOVD 120(RSP), F11 - FMOVD 128(RSP), F12 - FMOVD 136(RSP), F13 - FMOVD 144(RSP), F14 - FMOVD 152(RSP), F15 + MOVD 96(RSP), g + FMOVD 104(RSP), F8 + FMOVD 112(RSP), F9 + FMOVD 120(RSP), F10 + FMOVD 128(RSP), F11 + FMOVD 136(RSP), F12 + FMOVD 144(RSP), F13 + FMOVD 152(RSP), F14 + FMOVD 160(RSP), F15 + RET TEXT _rt0_arm64_darwin_lib_go(SB),NOSPLIT,$0 diff --git a/src/runtime/stack.go b/src/runtime/stack.go index e40fa9cc1b4..d83e9d6722f 100644 --- a/src/runtime/stack.go +++ b/src/runtime/stack.go @@ -64,8 +64,8 @@ const ( // StackSystem is a number of additional bytes to add // to each stack below the usual guard area for OS-specific // purposes like signal handling. Used on Windows, Plan 9, - // and Darwin/ARM because they do not use a separate stack. - _StackSystem = sys.GoosWindows*512*sys.PtrSize + sys.GoosPlan9*512 + sys.GoosDarwin*sys.GoarchArm*1024 + // and iOS because they do not use a separate stack. + _StackSystem = sys.GoosWindows*512*sys.PtrSize + sys.GoosPlan9*512 + sys.GoosDarwin*sys.GoarchArm*1024 + sys.GoosDarwin*sys.GoarchArm64*1024 // The minimum size of stack used by Go code _StackMin = 2048 diff --git a/src/runtime/sys_darwin_arm.s b/src/runtime/sys_darwin_arm.s index a940d95732c..5f6c9034374 100644 --- a/src/runtime/sys_darwin_arm.s +++ b/src/runtime/sys_darwin_arm.s @@ -61,14 +61,12 @@ TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0 MOVW $1002, R1 MOVW R0, (R1) // fail hard -TEXT runtime·raiseproc(SB),NOSPLIT,$24 - MOVW $SYS_getpid, R12 - SWI $0x80 +TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 + MOVW 0(R0), R8 // signal + BL libc_getpid(SB) // arg 1 pid already in R0 from getpid - MOVW sig+0(FP), R1 // arg 2 - signal - MOVW $1, R2 // arg 3 - posix - MOVW $SYS_kill, R12 - SWI $0x80 + MOVW R8, R1 // arg 2 signal + BL libc_kill(SB) RET TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 @@ -174,91 +172,89 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 MOVW R4, R13 RET -// Sigtramp's job is to call the actual signal handler. -// It is called with the following arguments on the stack: -// LR "return address" - ignored -// R0 actual handler -// R1 siginfo style - ignored -// R2 signal number -// R3 siginfo -// -4(FP) context, beware that 0(FP) is the saved LR TEXT runtime·sigtramp(SB),NOSPLIT,$0 + // Reserve space for callee-save registers and arguments. + SUB $36, R13 + + MOVW R4, 12(R13) + MOVW R5, 16(R13) + MOVW R6, 20(R13) + MOVW R7, 24(R13) + MOVW R8, 28(R13) + MOVW R11, 32(R13) + + // Save arguments. + MOVW R0, 4(R13) // sig + MOVW R1, 8(R13) // info + MOVW R2, 12(R13) // ctx + // this might be called in external code context, // where g is not set. - // first save R0, because runtime·load_g will clobber it - MOVM.DB.W [R0], (R13) MOVB runtime·iscgo(SB), R0 CMP $0, R0 BL.NE runtime·load_g(SB) - CMP $0, g - BNE cont - // fake function call stack frame for badsignal - // we only need to pass R2 (signal number), but - // badsignal will expect R2 at 4(R13), so we also - // push R1 onto stack. turns out we do need R1 - // to do sigreturn. - MOVM.DB.W [R1,R2], (R13) - MOVW $runtime·badsignal(SB), R11 - BL (R11) - MOVM.IA.W [R1], (R13) // saved infostype - ADD $(4+4), R13 // +4: also need to remove the pushed R0. - MOVW ucontext-4(FP), R0 // load ucontext - B ret + MOVW R13, R6 + CMP $0, g + BEQ nog -cont: - // Restore R0 - MOVM.IA.W (R13), [R0] - - // NOTE: some Darwin/ARM kernels always use the main stack to run the - // signal handler. We need to switch to gsignal ourselves. + // iOS always use the main stack to run the signal handler. + // We need to switch to gsignal ourselves. MOVW g_m(g), R11 MOVW m_gsignal(R11), R5 MOVW (g_stack+stack_hi)(R5), R6 - SUB $28, R6 - // copy arguments for call to sighandler - MOVW R2, 4(R6) // signal num - MOVW R3, 8(R6) // signal info - MOVW g, 16(R6) // old_g - MOVW context-4(FP), R4 - MOVW R4, 12(R6) // context +nog: + // Restore arguments. + MOVW 4(R13), R0 + MOVW 8(R13), R1 + MOVW 12(R13), R2 - // Backup ucontext and infostyle - MOVW R4, 20(R6) - MOVW R1, 24(R6) + // Reserve space for args and the stack pointer on the + // gsignal stack. + SUB $24, R6 + // Save stack pointer. + MOVW R13, R4 + MOVW R4, 16(R6) + // Switch to gsignal stack. + MOVW R6, R13 - // switch stack and g - MOVW R6, R13 // sigtramp is not re-entrant, so no need to back up R13. - MOVW R5, g + // Call sigtrampgo + MOVW R0, 4(R13) + MOVW R1, 8(R13) + MOVW R2, 12(R13) + BL runtime·sigtrampgo(SB) - BL (R0) + // Switch to old stack. + MOVW 16(R13), R5 + MOVW R5, R13 - // call sigreturn - MOVW 20(R13), R0 // saved ucontext - MOVW 24(R13), R1 // saved infostyle -ret: - MOVW $SYS_sigreturn, R12 // sigreturn(ucontext, infostyle) - SWI $0x80 + // Restore callee-save registers. + MOVW 12(R13), R4 + MOVW 16(R13), R5 + MOVW 20(R13), R6 + MOVW 24(R13), R7 + MOVW 28(R13), R8 + MOVW 32(R13), R11 - // if sigreturn fails, we can do nothing but exit - B runtime·exit(SB) + ADD $36, R13 -TEXT runtime·sigprocmask(SB),NOSPLIT,$0 - MOVW how+0(FP), R0 - MOVW new+4(FP), R1 - MOVW old+8(FP), R2 - MOVW $SYS_pthread_sigmask, R12 - SWI $0x80 - BL.CS notok<>(SB) RET -TEXT runtime·sigaction(SB),NOSPLIT,$0 - MOVW mode+0(FP), R0 - MOVW new+4(FP), R1 - MOVW old+8(FP), R2 - MOVW $SYS_sigaction, R12 - SWI $0x80 +TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 + MOVW 4(R0), R1 // arg 2 new + MOVW 8(R0), R2 // arg 3 old + MOVW 0(R0), R0 // arg 1 how + BL libc_pthread_sigmask(SB) + CMP $0, R0 + BL.NE notok<>(SB) + RET + +TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 + MOVW 4(R0), R1 // arg 2 new + MOVW 8(R0), R2 // arg 3 old + MOVW 0(R0), R0 // arg 1 how + BL libc_sigaction(SB) RET TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 @@ -387,10 +383,11 @@ TEXT runtime·closeonexec(SB),NOSPLIT,$0 SWI $0x80 RET -// sigaltstack on some darwin/arm version is buggy and will always -// run the signal handler on the main stack, so our sigtramp has +// sigaltstack is not supported on iOS, so our sigtramp has // to do the stack switch ourselves. -TEXT runtime·sigaltstack(SB),NOSPLIT,$0 +TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 + MOVW $43, R0 + BL libc_exit(SB) RET // Thread related functions diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s index d13e44afcfa..c21a5566fa0 100644 --- a/src/runtime/sys_darwin_arm64.s +++ b/src/runtime/sys_darwin_arm64.s @@ -61,14 +61,12 @@ TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0 MOVD $1002, R1 MOVD R0, (R1) // fail hard -TEXT runtime·raiseproc(SB),NOSPLIT,$0 - MOVW $SYS_getpid, R16 - SVC $0x80 +TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 + MOVD 0(R0), R19 // signal + BL libc_getpid(SB) // arg 1 pid already in R0 from getpid - MOVW sig+0(FP), R1 // arg 2 - signal - MOVW $1, R2 // arg 3 - posix - MOVW $SYS_kill, R16 - SVC $0x80 + MOVD R19, R1 // arg 2 signal + BL libc_kill(SB) RET TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 @@ -158,95 +156,104 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 BL (R11) RET -// Sigtramp's job is to call the actual signal handler. -// It is called with the following arguments on the stack: -// LR "return address" - ignored -// R0 actual handler -// R1 siginfo style - ignored -// R2 signal number -// R3 siginfo -// R4 context TEXT runtime·sigtramp(SB),NOSPLIT,$0 + // Reserve space for callee-save registers and arguments. + SUB $(8*16), RSP + + // Save callee-save registers. + MOVD R19, (8*4)(RSP) + MOVD R20, (8*5)(RSP) + MOVD R21, (8*6)(RSP) + MOVD R22, (8*7)(RSP) + MOVD R23, (8*8)(RSP) + MOVD R24, (8*9)(RSP) + MOVD R25, (8*10)(RSP) + MOVD R26, (8*11)(RSP) + MOVD R27, (8*12)(RSP) + MOVD g, (8*13)(RSP) + MOVD R29, (8*14)(RSP) + + // Save arguments. + MOVW R0, (8*1)(RSP) // sig + MOVD R1, (8*2)(RSP) // info + MOVD R2, (8*3)(RSP) // ctx + // this might be called in external code context, // where g is not set. - // first save R0, because runtime·load_g will clobber it - MOVD.W R0, -16(RSP) // note: stack must be 16-byte aligned MOVB runtime·iscgo(SB), R0 CMP $0, R0 BEQ 2(PC) BL runtime·load_g(SB) - CMP $0, g - BNE cont - // fake function call stack frame for badsignal - // we only need to pass R2 (signal number), but - // badsignal will expect R2 at 8(RSP), so we also - // push R1 onto stack. turns out we do need R1 - // to do sigreturn. - MOVD.W R1, -16(RSP) - MOVD R2, 8(RSP) - MOVD R4, 24(RSP) // save ucontext, badsignal might clobber R4 - MOVD $runtime·badsignal(SB), R26 - BL (R26) - MOVD 0(RSP), R1 // saved infostype - MOVD 24(RSP), R0 // the ucontext - ADD $(16+16), RSP - B ret - -cont: - // Restore R0 - MOVD.P 16(RSP), R0 - - // NOTE: some Darwin/ARM kernels always use the main stack to run the - // signal handler. We need to switch to gsignal ourselves. + MOVD RSP, R6 + CMP $0, g + BEQ nog + // iOS always use the main stack to run the signal handler. + // We need to switch to gsignal ourselves. MOVD g_m(g), R11 MOVD m_gsignal(R11), R5 MOVD (g_stack+stack_hi)(R5), R6 - SUB $64, R6 - // copy arguments for call to sighandler - MOVD R2, 8(R6) // signal num - MOVD R3, 16(R6) // signal info - MOVD R4, 24(R6) // context - MOVD g, 32(R6) // old_g +nog: + // Restore arguments. + MOVW (8*1)(RSP), R0 + MOVD (8*2)(RSP), R1 + MOVD (8*3)(RSP), R2 - // Backup ucontext and infostyle - MOVD R4, 40(R6) - MOVD R1, 48(R6) + // Reserve space for args and the stack pointer on the + // gsignal stack. + SUB $48, R6 + // Save stack pointer. + MOVD RSP, R4 + MOVD R4, (8*4)(R6) + // Switch to gsignal stack. + MOVD R6, RSP - // switch stack and g - MOVD R6, RSP // sigtramp is not re-entrant, so no need to back up RSP. - MOVD R5, g + // Call sigtrampgo. + MOVW R0, (8*1)(RSP) + MOVD R1, (8*2)(RSP) + MOVD R2, (8*3)(RSP) + MOVD $runtime·sigtrampgo(SB), R11 + BL (R11) - BL (R0) + // Switch to old stack. + MOVD (8*4)(RSP), R5 + MOVD R5, RSP - // call sigreturn - MOVD 40(RSP), R0 // saved ucontext - MOVD 48(RSP), R1 // saved infostyle -ret: - MOVW $SYS_sigreturn, R16 // sigreturn(ucontext, infostyle) - SVC $0x80 + // Restore callee-save registers. + MOVD (8*4)(RSP), R19 + MOVD (8*5)(RSP), R20 + MOVD (8*6)(RSP), R21 + MOVD (8*7)(RSP), R22 + MOVD (8*8)(RSP), R23 + MOVD (8*9)(RSP), R24 + MOVD (8*10)(RSP), R25 + MOVD (8*11)(RSP), R26 + MOVD (8*12)(RSP), R27 + MOVD (8*13)(RSP), g + MOVD (8*14)(RSP), R29 - // if sigreturn fails, we can do nothing but exit - B runtime·exit(SB) + ADD $(8*16), RSP -TEXT runtime·sigprocmask(SB),NOSPLIT,$0 - MOVW how+0(FP), R0 - MOVD new+8(FP), R1 - MOVD old+16(FP), R2 - MOVW $SYS_pthread_sigmask, R16 - SVC $0x80 - BCC 2(PC) + RET + +TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 + MOVD 8(R0), R1 // arg 2 new + MOVD 16(R0), R2 // arg 3 old + MOVW 0(R0), R0 // arg 1 how + BL libc_pthread_sigmask(SB) + CMP $0, R0 + BEQ 2(PC) BL notok<>(SB) RET -TEXT runtime·sigaction(SB),NOSPLIT,$0 - MOVW mode+0(FP), R0 - MOVD new+8(FP), R1 - MOVD old+16(FP), R2 - MOVW $SYS_sigaction, R16 - SVC $0x80 - BCC 2(PC) +TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 + MOVD 8(R0), R1 // arg 2 new + MOVD 16(R0), R2 // arg 3 old + MOVW 0(R0), R0 // arg 1 how + BL libc_sigaction(SB) + CMP $0, R0 + BEQ 2(PC) BL notok<>(SB) RET @@ -375,10 +382,12 @@ TEXT runtime·closeonexec(SB),NOSPLIT,$0 SVC $0x80 RET -// sigaltstack on some darwin/arm version is buggy and will always +// sigaltstack on iOS is not supported and will always // run the signal handler on the main stack, so our sigtramp has // to do the stack switch ourselves. -TEXT runtime·sigaltstack(SB),NOSPLIT,$0 +TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 + MOVW $43, R0 + BL libc_exit(SB) RET // Thread related functions