BL (R11)
RET
+// Called from c-abi, R0: sig, R1: info, R2: cxt
TEXT runtime·sigtramp(SB),NOSPLIT,$192
// Save callee-save registers in the case of signal forwarding.
// Please refer to https://golang.org/issue/31827 .
RET
-TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
- MOVD $runtime·sigtramp(SB), R3
- B (R3)
+// Called from c-abi, R0: sig, R1: info, R2: cxt
+TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$192
+ // TODO(eric): In multiple places we need to save and restore the
+ // callee-saved registers, we can define a macro for this.
+ // Save callee-save registers because it's a callback from c code.
+ 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)
+ FMOVD F8, 8*15(RSP)
+ FMOVD F9, 8*16(RSP)
+ FMOVD F10, 8*17(RSP)
+ FMOVD F11, 8*18(RSP)
+ FMOVD F12, 8*19(RSP)
+ FMOVD F13, 8*20(RSP)
+ FMOVD F14, 8*21(RSP)
+ FMOVD F15, 8*22(RSP)
+
+ MOVW R0, 8(RSP) // sig
+ MOVD R1, 16(RSP) // info
+ MOVD R2, 24(RSP) // ctx
+ CALL runtime·sigprofNonGo(SB)
+
+ // 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
+ FMOVD 8*15(RSP), F8
+ FMOVD 8*16(RSP), F9
+ FMOVD 8*17(RSP), F10
+ FMOVD 8*18(RSP), F11
+ FMOVD 8*19(RSP), F12
+ FMOVD 8*20(RSP), F13
+ FMOVD 8*21(RSP), F14
+ FMOVD 8*22(RSP), F15
+ RET
+
+// Called from c-abi, R0: sig, R1: info, R2: cxt
+TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
+ // The stack unwinder, presumably written in C, may not be able to
+ // handle Go frame correctly. So, this function is NOFRAME, and we
+ // save/restore LR manually.
+ MOVD LR, R10
+ // Save R27, g because they will be clobbered,
+ // we need to restore them before jump to sigtramp.
+ MOVD R27, R11
+ MOVD g, R12
+
+ // If no traceback function, do usual sigtramp.
+ MOVD runtime·cgoTraceback(SB), R6
+ CBZ R6, sigtramp
+
+ // If no traceback support function, which means that
+ // runtime/cgo was not linked in, do usual sigtramp.
+ MOVD _cgo_callers(SB), R7
+ CBZ R7, sigtramp
+
+ // Figure out if we are currently in a cgo call.
+ // If not, just do usual sigtramp.
+ // first save R0, because runtime·load_g will clobber it.
+ MOVD R0, R8
+ // Set up g register.
+ CALL runtime·load_g(SB)
+ MOVD R8, R0
+
+ CBZ g, sigtrampnog // g == nil
+ MOVD g_m(g), R6
+ CBZ R6, sigtramp // g.m == nil
+ MOVW m_ncgo(R6), R7
+ CBZW R7, sigtramp // g.m.ncgo = 0
+ MOVD m_curg(R6), R8
+ CBZ R8, sigtramp // g.m.curg == nil
+ MOVD g_syscallsp(R8), R7
+ CBZ R7, sigtramp // g.m.curg.syscallsp == 0
+ MOVD m_cgoCallers(R6), R4 // R4 is the fifth arg in C calling convention.
+ CBZ R4, sigtramp // g.m.cgoCallers == nil
+ MOVW m_cgoCallersUse(R6), R8
+ CBNZW R8, sigtramp // g.m.cgoCallersUse != 0
+
+ // Jump to a function in runtime/cgo.
+ // That function, written in C, will call the user's traceback
+ // function with proper unwind info, and will then call back here.
+ // The first three arguments, and the fifth, are already in registers.
+ // Set the two remaining arguments now.
+ MOVD runtime·cgoTraceback(SB), R3
+ MOVD $runtime·sigtramp(SB), R5
+ MOVD _cgo_callers(SB), R13
+ MOVD R10, LR // restore
+ MOVD R11, R27
+ MOVD R12, g
+ B (R13)
+
+sigtramp:
+ MOVD R10, LR // restore
+ MOVD R11, R27
+ MOVD R12, g
+ B runtime·sigtramp(SB)
+
+sigtrampnog:
+ // Signal arrived on a non-Go thread. If this is SIGPROF, get a
+ // stack trace.
+ CMPW $27, R0 // 27 == SIGPROF
+ BNE sigtramp
+
+ // Lock sigprofCallersUse (cas from 0 to 1).
+ MOVW $1, R7
+ MOVD $runtime·sigprofCallersUse(SB), R8
+load_store_loop:
+ LDAXRW (R8), R9
+ CBNZW R9, sigtramp // Skip stack trace if already locked.
+ STLXRW R7, (R8), R9
+ CBNZ R9, load_store_loop
+
+ // Jump to the traceback function in runtime/cgo.
+ // It will call back to sigprofNonGo, which will ignore the
+ // arguments passed in registers.
+ // First three arguments to traceback function are in registers already.
+ MOVD runtime·cgoTraceback(SB), R3
+ MOVD $runtime·sigprofCallers(SB), R4
+ MOVD $runtime·sigprofNonGoWrapper<>(SB), R5
+ MOVD _cgo_callers(SB), R13
+ MOVD R10, LR // restore
+ MOVD R11, R27
+ MOVD R12, g
+ B (R13)
TEXT runtime·sysMmap(SB),NOSPLIT|NOFRAME,$0
MOVD addr+0(FP), R0