1
0
mirror of https://github.com/golang/go synced 2024-11-19 05:54:44 -07:00

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 <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Elias Naur 2018-06-07 12:19:42 +02:00 committed by Keith Randall
parent ec989337c5
commit 021c39d7a3
8 changed files with 261 additions and 203 deletions

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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