// 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
// 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
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)
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.
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.
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
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
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.
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.
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
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
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.
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)
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
// 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
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
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
-
-cont:
- // Restore R0
- MOVM.IA.W (R13), [R0]
+ MOVW R13, R6
+ CMP $0, g
+ BEQ nog
- // 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
-
- // 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
- B runtime·exit(SB)
+nog:
+ // 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
-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
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
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
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
-
- // Backup ucontext and infostyle
- MOVD R4, 40(R6)
- MOVD R1, 48(R6)
+nog:
+ // Restore arguments.
+ MOVW (8*1)(RSP), R0
+ MOVD (8*2)(RSP), R1
+ MOVD (8*3)(RSP), R2
+
+ // 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
+
+ // 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
- MOVD R6, RSP // sigtramp is not re-entrant, so no need to back up RSP.
- MOVD R5, g
+ // Switch to old stack.
+ MOVD (8*4)(RSP), R5
+ 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
- MOVD 40(RSP), R0 // saved ucontext
- MOVD 48(RSP), R1 // saved infostyle
-ret:
- MOVW $SYS_sigreturn, R16 // sigreturn(ucontext, infostyle)
- SVC $0x80
+ ADD $(8*16), RSP
- // if sigreturn fails, we can do nothing but exit
- B runtime·exit(SB)
+ RET
-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)
+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
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