Commit 021c39d7 authored by Elias Naur's avatar Elias Naur Committed by Keith Randall

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: default avatarKeith Randall <khr@golang.org>
parent ec989337
// darwin/arm-specific vet whitelist. See readme.txt for details. // 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. // Ok.
runtime/asm_arm.s: [arm] sigreturn: function sigreturn missing Go declaration runtime/asm_arm.s: [arm] sigreturn: function sigreturn missing Go declaration
// darwin/arm64-specific vet whitelist. See readme.txt for details. // 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 runtime/asm_arm64.s: [arm64] sigreturn: function sigreturn missing Go declaration
...@@ -36,25 +36,28 @@ TEXT _rt0_arm_lib(SB),NOSPLIT,$104 ...@@ -36,25 +36,28 @@ TEXT _rt0_arm_lib(SB),NOSPLIT,$104
MOVW R6, 20(R13) MOVW R6, 20(R13)
MOVW R7, 24(R13) MOVW R7, 24(R13)
MOVW R8, 28(R13) MOVW R8, 28(R13)
MOVW R11, 32(R13) MOVW g, 32(R13)
MOVW R11, 36(R13)
// Skip floating point registers on GOARM < 6. // Skip floating point registers on GOARM < 6.
MOVB runtime·goarm(SB), R11 MOVB runtime·goarm(SB), R11
CMP $6, R11 CMP $6, R11
BLT skipfpsave BLT skipfpsave
MOVD F8, (32+8*1)(R13) MOVD F8, (40+8*0)(R13)
MOVD F9, (32+8*2)(R13) MOVD F9, (40+8*1)(R13)
MOVD F10, (32+8*3)(R13) MOVD F10, (40+8*2)(R13)
MOVD F11, (32+8*4)(R13) MOVD F11, (40+8*3)(R13)
MOVD F12, (32+8*5)(R13) MOVD F12, (40+8*4)(R13)
MOVD F13, (32+8*6)(R13) MOVD F13, (40+8*5)(R13)
MOVD F14, (32+8*7)(R13) MOVD F14, (40+8*6)(R13)
MOVD F15, (32+8*8)(R13) MOVD F15, (40+8*7)(R13)
skipfpsave: skipfpsave:
// Save argc/argv. // Save argc/argv.
MOVW R0, _rt0_arm_lib_argc<>(SB) MOVW R0, _rt0_arm_lib_argc<>(SB)
MOVW R1, _rt0_arm_lib_argv<>(SB) MOVW R1, _rt0_arm_lib_argv<>(SB)
MOVW $0, g // Initialize g.
// Synchronous initialization. // Synchronous initialization.
CALL runtime·libpreinit(SB) CALL runtime·libpreinit(SB)
...@@ -77,21 +80,22 @@ rr: ...@@ -77,21 +80,22 @@ rr:
MOVB runtime·goarm(SB), R11 MOVB runtime·goarm(SB), R11
CMP $6, R11 CMP $6, R11
BLT skipfprest BLT skipfprest
MOVD (32+8*1)(R13), F8 MOVD (40+8*0)(R13), F8
MOVD (32+8*2)(R13), F9 MOVD (40+8*1)(R13), F9
MOVD (32+8*3)(R13), F10 MOVD (40+8*2)(R13), F10
MOVD (32+8*4)(R13), F11 MOVD (40+8*3)(R13), F11
MOVD (32+8*5)(R13), F12 MOVD (40+8*4)(R13), F12
MOVD (32+8*6)(R13), F13 MOVD (40+8*5)(R13), F13
MOVD (32+8*7)(R13), F14 MOVD (40+8*6)(R13), F14
MOVD (32+8*8)(R13), F15 MOVD (40+8*7)(R13), F15
skipfprest: skipfprest:
MOVW 12(R13), R4 MOVW 12(R13), R4
MOVW 16(R13), R5 MOVW 16(R13), R5
MOVW 20(R13), R6 MOVW 20(R13), R6
MOVW 24(R13), R7 MOVW 24(R13), R7
MOVW 28(R13), R8 MOVW 28(R13), R8
MOVW 32(R13), R11 MOVW 32(R13), g
MOVW 36(R13), R11
RET RET
// _rt0_arm_lib_go initializes the Go runtime. // _rt0_arm_lib_go initializes the Go runtime.
...@@ -582,6 +586,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12 ...@@ -582,6 +586,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12
MOVW arg+4(FP), R0 MOVW arg+4(FP), R0
MOVW R13, R2 MOVW R13, R2
CMP $0, g
BEQ nosave
MOVW g, R4 MOVW g, R4
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
...@@ -590,10 +596,10 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12 ...@@ -590,10 +596,10 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12
MOVW g_m(g), R8 MOVW g_m(g), R8
MOVW m_gsignal(R8), R3 MOVW m_gsignal(R8), R3
CMP R3, g CMP R3, g
BEQ noswitch BEQ nosave
MOVW m_g0(R8), R3 MOVW m_g0(R8), R3
CMP R3, g CMP R3, g
BEQ noswitch BEQ nosave
BL gosave<>(SB) BL gosave<>(SB)
MOVW R0, R5 MOVW R0, R5
MOVW R3, R0 MOVW R3, R0
...@@ -602,7 +608,6 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12 ...@@ -602,7 +608,6 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12
MOVW (g_sched+gobuf_sp)(g), R13 MOVW (g_sched+gobuf_sp)(g), R13
// Now on a scheduling stack (a pthread-created stack). // Now on a scheduling stack (a pthread-created stack).
noswitch:
SUB $24, R13 SUB $24, R13
BIC $0x7, R13 // alignment for gcc ABI BIC $0x7, R13 // alignment for gcc ABI
MOVW R4, 20(R13) // save old g MOVW R4, 20(R13) // save old g
...@@ -624,6 +629,30 @@ noswitch: ...@@ -624,6 +629,30 @@ noswitch:
MOVW R0, ret+8(FP) MOVW R0, ret+8(FP)
RET 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) // cgocallback(void (*fn)(void*), void *frame, uintptr framesize, uintptr ctxt)
// Turn the fn into a Go func (by taking its address) and call // Turn the fn into a Go func (by taking its address) and call
// cgocallback_gofunc. // cgocallback_gofunc.
......
...@@ -863,6 +863,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20 ...@@ -863,6 +863,8 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
MOVD arg+8(FP), R0 MOVD arg+8(FP), R0
MOVD RSP, R2 // save original stack pointer MOVD RSP, R2 // save original stack pointer
CMP $0, g
BEQ nosave
MOVD g, R4 MOVD g, R4
// Figure out if we need to switch to m->g0 stack. // Figure out if we need to switch to m->g0 stack.
...@@ -871,10 +873,12 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20 ...@@ -871,10 +873,12 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
MOVD g_m(g), R8 MOVD g_m(g), R8
MOVD m_gsignal(R8), R3 MOVD m_gsignal(R8), R3
CMP R3, g CMP R3, g
BEQ noswitch BEQ nosave
MOVD m_g0(R8), R3 MOVD m_g0(R8), R3
CMP R3, g CMP R3, g
BEQ noswitch BEQ nosave
// Switch to system stack.
MOVD R0, R9 // gosave<> and save_g might clobber R0 MOVD R0, R9 // gosave<> and save_g might clobber R0
BL gosave<>(SB) BL gosave<>(SB)
MOVD R3, g MOVD R3, g
...@@ -884,12 +888,10 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20 ...@@ -884,12 +888,10 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
MOVD R9, R0 MOVD R9, R0
// Now on a scheduling stack (a pthread-created stack). // Now on a scheduling stack (a pthread-created stack).
noswitch:
// Save room for two of our pointers /*, plus 32 bytes of callee // Save room for two of our pointers /*, plus 32 bytes of callee
// save area that lives on the caller stack. */ // save area that lives on the caller stack. */
MOVD RSP, R13 MOVD RSP, R13
SUB $16, R13 SUB $16, R13
BIC $0xf, R13 // alignment for gcc ABI
MOVD R13, RSP MOVD R13, RSP
MOVD R4, 0(RSP) // save old g on stack MOVD R4, 0(RSP) // save old g on stack
MOVD (g_stack+stack_hi)(R4), R4 MOVD (g_stack+stack_hi)(R4), R4
...@@ -910,6 +912,30 @@ noswitch: ...@@ -910,6 +912,30 @@ noswitch:
MOVW R0, ret+16(FP) MOVW R0, ret+16(FP)
RET 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) // cgocallback(void (*fn)(void*), void *frame, uintptr framesize, uintptr ctxt)
// Turn the fn into a Go func (by taking its address) and call // Turn the fn into a Go func (by taking its address) and call
// cgocallback_gofunc. // cgocallback_gofunc.
......
...@@ -26,18 +26,21 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$168 ...@@ -26,18 +26,21 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$168
MOVD R25, 72(RSP) MOVD R25, 72(RSP)
MOVD R26, 80(RSP) MOVD R26, 80(RSP)
MOVD R27, 88(RSP) MOVD R27, 88(RSP)
FMOVD F8, 96(RSP) MOVD g, 96(RSP)
FMOVD F9, 104(RSP) FMOVD F8, 104(RSP)
FMOVD F10, 112(RSP) FMOVD F9, 112(RSP)
FMOVD F11, 120(RSP) FMOVD F10, 120(RSP)
FMOVD F12, 128(RSP) FMOVD F11, 128(RSP)
FMOVD F13, 136(RSP) FMOVD F12, 136(RSP)
FMOVD F14, 144(RSP) FMOVD F13, 144(RSP)
FMOVD F15, 152(RSP) FMOVD F14, 152(RSP)
FMOVD F15, 160(RSP)
MOVD R0, _rt0_arm64_darwin_lib_argc<>(SB) MOVD R0, _rt0_arm64_darwin_lib_argc<>(SB)
MOVD R1, _rt0_arm64_darwin_lib_argv<>(SB) MOVD R1, _rt0_arm64_darwin_lib_argv<>(SB)
MOVD $0, g // initialize g to nil
// Synchronous initialization. // Synchronous initialization.
MOVD $runtime·libpreinit(SB), R4 MOVD $runtime·libpreinit(SB), R4
BL (R4) BL (R4)
...@@ -58,14 +61,16 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$168 ...@@ -58,14 +61,16 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$168
MOVD 72(RSP), R25 MOVD 72(RSP), R25
MOVD 80(RSP), R26 MOVD 80(RSP), R26
MOVD 88(RSP), R27 MOVD 88(RSP), R27
FMOVD 96(RSP), F8 MOVD 96(RSP), g
FMOVD 104(RSP), F9 FMOVD 104(RSP), F8
FMOVD 112(RSP), F10 FMOVD 112(RSP), F9
FMOVD 120(RSP), F11 FMOVD 120(RSP), F10
FMOVD 128(RSP), F12 FMOVD 128(RSP), F11
FMOVD 136(RSP), F13 FMOVD 136(RSP), F12
FMOVD 144(RSP), F14 FMOVD 144(RSP), F13
FMOVD 152(RSP), F15 FMOVD 152(RSP), F14
FMOVD 160(RSP), F15
RET RET
TEXT _rt0_arm64_darwin_lib_go(SB),NOSPLIT,$0 TEXT _rt0_arm64_darwin_lib_go(SB),NOSPLIT,$0
......
...@@ -64,8 +64,8 @@ const ( ...@@ -64,8 +64,8 @@ const (
// StackSystem is a number of additional bytes to add // StackSystem is a number of additional bytes to add
// to each stack below the usual guard area for OS-specific // to each stack below the usual guard area for OS-specific
// purposes like signal handling. Used on Windows, Plan 9, // purposes like signal handling. Used on Windows, Plan 9,
// and Darwin/ARM because they do not use a separate stack. // and iOS because they do not use a separate stack.
_StackSystem = sys.GoosWindows*512*sys.PtrSize + sys.GoosPlan9*512 + sys.GoosDarwin*sys.GoarchArm*1024 _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 // The minimum size of stack used by Go code
_StackMin = 2048 _StackMin = 2048
......
...@@ -61,14 +61,12 @@ TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0 ...@@ -61,14 +61,12 @@ TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0
MOVW $1002, R1 MOVW $1002, R1
MOVW R0, (R1) // fail hard MOVW R0, (R1) // fail hard
TEXT runtime·raiseproc(SB),NOSPLIT,$24 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
MOVW $SYS_getpid, R12 MOVW 0(R0), R8 // signal
SWI $0x80 BL libc_getpid(SB)
// arg 1 pid already in R0 from getpid // arg 1 pid already in R0 from getpid
MOVW sig+0(FP), R1 // arg 2 - signal MOVW R8, R1 // arg 2 signal
MOVW $1, R2 // arg 3 - posix BL libc_kill(SB)
MOVW $SYS_kill, R12
SWI $0x80
RET RET
TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
...@@ -174,91 +172,89 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 ...@@ -174,91 +172,89 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
MOVW R4, R13 MOVW R4, R13
RET 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 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, // this might be called in external code context,
// where g is not set. // 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 MOVB runtime·iscgo(SB), R0
CMP $0, R0 CMP $0, R0
BL.NE runtime·load_g(SB) BL.NE runtime·load_g(SB)
MOVW R13, R6
CMP $0, g CMP $0, g
BNE cont BEQ nog
// 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
cont:
// Restore R0
MOVM.IA.W (R13), [R0]
// NOTE: some Darwin/ARM kernels always use the main stack to run the // iOS always use the main stack to run the signal handler.
// signal handler. We need to switch to gsignal ourselves. // We need to switch to gsignal ourselves.
MOVW g_m(g), R11 MOVW g_m(g), R11
MOVW m_gsignal(R11), R5 MOVW m_gsignal(R11), R5
MOVW (g_stack+stack_hi)(R5), R6 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
// Backup ucontext and infostyle
MOVW R4, 20(R6)
MOVW R1, 24(R6)
// switch stack and g
MOVW R6, R13 // sigtramp is not re-entrant, so no need to back up R13.
MOVW R5, g
BL (R0)
// call sigreturn
MOVW 20(R13), R0 // saved ucontext
MOVW 24(R13), R1 // saved infostyle
ret:
MOVW $SYS_sigreturn, R12 // sigreturn(ucontext, infostyle)
SWI $0x80
// if sigreturn fails, we can do nothing but exit nog:
B runtime·exit(SB) // Restore arguments.
MOVW 4(R13), R0
MOVW 8(R13), R1
MOVW 12(R13), R2
// 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
// Call sigtrampgo
MOVW R0, 4(R13)
MOVW R1, 8(R13)
MOVW R2, 12(R13)
BL runtime·sigtrampgo(SB)
// Switch to old stack.
MOVW 16(R13), R5
MOVW R5, R13
// 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
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 RET
TEXT runtime·sigaction(SB),NOSPLIT,$0 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
MOVW mode+0(FP), R0 MOVW 4(R0), R1 // arg 2 new
MOVW new+4(FP), R1 MOVW 8(R0), R2 // arg 3 old
MOVW old+8(FP), R2 MOVW 0(R0), R0 // arg 1 how
MOVW $SYS_sigaction, R12 BL libc_pthread_sigmask(SB)
SWI $0x80 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 RET
TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
...@@ -387,10 +383,11 @@ TEXT runtime·closeonexec(SB),NOSPLIT,$0 ...@@ -387,10 +383,11 @@ TEXT runtime·closeonexec(SB),NOSPLIT,$0
SWI $0x80 SWI $0x80
RET RET
// sigaltstack on some darwin/arm version is buggy and will always // sigaltstack is not supported on iOS, so our sigtramp has
// run the signal handler on the main stack, so our sigtramp has
// to do the stack switch ourselves. // 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 RET
// Thread related functions // Thread related functions
......
...@@ -61,14 +61,12 @@ TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0 ...@@ -61,14 +61,12 @@ TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0
MOVD $1002, R1 MOVD $1002, R1
MOVD R0, (R1) // fail hard MOVD R0, (R1) // fail hard
TEXT runtime·raiseproc(SB),NOSPLIT,$0 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
MOVW $SYS_getpid, R16 MOVD 0(R0), R19 // signal
SVC $0x80 BL libc_getpid(SB)
// arg 1 pid already in R0 from getpid // arg 1 pid already in R0 from getpid
MOVW sig+0(FP), R1 // arg 2 - signal MOVD R19, R1 // arg 2 signal
MOVW $1, R2 // arg 3 - posix BL libc_kill(SB)
MOVW $SYS_kill, R16
SVC $0x80
RET RET
TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
...@@ -158,95 +156,104 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 ...@@ -158,95 +156,104 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
BL (R11) BL (R11)
RET 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 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, // this might be called in external code context,
// where g is not set. // 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 MOVB runtime·iscgo(SB), R0
CMP $0, R0 CMP $0, R0
BEQ 2(PC) BEQ 2(PC)
BL runtime·load_g(SB) BL runtime·load_g(SB)
MOVD RSP, R6
CMP $0, g CMP $0, g
BNE cont BEQ nog
// fake function call stack frame for badsignal // iOS always use the main stack to run the signal handler.
// we only need to pass R2 (signal number), but // We need to switch to gsignal ourselves.
// 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 g_m(g), R11 MOVD g_m(g), R11
MOVD m_gsignal(R11), R5 MOVD m_gsignal(R11), R5
MOVD (g_stack+stack_hi)(R5), R6 MOVD (g_stack+stack_hi)(R5), R6
SUB $64, R6
// copy arguments for call to sighandler nog:
MOVD R2, 8(R6) // signal num // Restore arguments.
MOVD R3, 16(R6) // signal info MOVW (8*1)(RSP), R0
MOVD R4, 24(R6) // context MOVD (8*2)(RSP), R1
MOVD g, 32(R6) // old_g MOVD (8*3)(RSP), R2
// Backup ucontext and infostyle // Reserve space for args and the stack pointer on the
MOVD R4, 40(R6) // gsignal stack.
MOVD R1, 48(R6) SUB $48, R6
// Save stack pointer.
MOVD RSP, R4
MOVD R4, (8*4)(R6)
// Switch to gsignal stack.
MOVD R6, RSP
// Call sigtrampgo.
MOVW R0, (8*1)(RSP)
MOVD R1, (8*2)(RSP)
MOVD R2, (8*3)(RSP)
MOVD $runtime·sigtrampgo(SB), R11
BL (R11)
// switch stack and g // Switch to old stack.
MOVD R6, RSP // sigtramp is not re-entrant, so no need to back up RSP. MOVD (8*4)(RSP), R5
MOVD R5, g MOVD R5, RSP
BL (R0) // 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
// call sigreturn ADD $(8*16), RSP
MOVD 40(RSP), R0 // saved ucontext
MOVD 48(RSP), R1 // saved infostyle
ret:
MOVW $SYS_sigreturn, R16 // sigreturn(ucontext, infostyle)
SVC $0x80
// if sigreturn fails, we can do nothing but exit RET
B runtime·exit(SB)
TEXT runtime·sigprocmask(SB),NOSPLIT,$0 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
MOVW how+0(FP), R0 MOVD 8(R0), R1 // arg 2 new
MOVD new+8(FP), R1 MOVD 16(R0), R2 // arg 3 old
MOVD old+16(FP), R2 MOVW 0(R0), R0 // arg 1 how
MOVW $SYS_pthread_sigmask, R16 BL libc_pthread_sigmask(SB)
SVC $0x80 CMP $0, R0
BCC 2(PC) BEQ 2(PC)
BL notok<>(SB) BL notok<>(SB)
RET RET
TEXT runtime·sigaction(SB),NOSPLIT,$0 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
MOVW mode+0(FP), R0 MOVD 8(R0), R1 // arg 2 new
MOVD new+8(FP), R1 MOVD 16(R0), R2 // arg 3 old
MOVD old+16(FP), R2 MOVW 0(R0), R0 // arg 1 how
MOVW $SYS_sigaction, R16 BL libc_sigaction(SB)
SVC $0x80 CMP $0, R0
BCC 2(PC) BEQ 2(PC)
BL notok<>(SB) BL notok<>(SB)
RET RET
...@@ -375,10 +382,12 @@ TEXT runtime·closeonexec(SB),NOSPLIT,$0 ...@@ -375,10 +382,12 @@ TEXT runtime·closeonexec(SB),NOSPLIT,$0
SVC $0x80 SVC $0x80
RET 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 // run the signal handler on the main stack, so our sigtramp has
// to do the stack switch ourselves. // 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 RET
// Thread related functions // Thread related functions
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment