aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorElias Naur <elias.naur@gmail.com>2018-06-07 12:19:42 +0200
committerKeith Randall <khr@golang.org>2018-06-12 17:05:46 +0000
commit021c39d7a3361290d9e29497cf2a4a8fd2ee7b5c (patch)
tree573c7176129e0e5a0ed8b30b867453f04de0aa4b /src
parentec989337c5d3203d52de1a2314813996c711fce6 (diff)
downloadgo-021c39d7a3361290d9e29497cf2a4a8fd2ee7b5c.tar.xz
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>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/vet/all/whitelist/darwin_arm.txt6
-rw-r--r--src/cmd/vet/all/whitelist/darwin_arm64.txt2
-rw-r--r--src/runtime/asm_arm.s71
-rw-r--r--src/runtime/asm_arm64.s34
-rw-r--r--src/runtime/rt0_darwin_arm64.s37
-rw-r--r--src/runtime/stack.go4
-rw-r--r--src/runtime/sys_darwin_arm.s147
-rw-r--r--src/runtime/sys_darwin_arm64.s163
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 8e935b6ff2..1c25c6a939 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 8cab997961..a1edb71383 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 545e58e9b0..6722ba760f 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 d1b90b056c..af389be9fe 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 719944e626..d039a8e0ab 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 e40fa9cc1b..d83e9d6722 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 a940d95732..5f6c903437 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 d13e44afcf..c21a5566fa 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