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:
parent
ec989337c5
commit
021c39d7a3
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user