aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sys_linux_ppc64x.s
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2017-10-20 14:26:28 -0400
committerCherry Zhang <cherryyz@google.com>2017-10-21 00:31:27 +0000
commit6fd1f825c1310e2a586a9ae0fc128a0b3c115b12 (patch)
treec8668e661354452a67238f6b3aadb2ffc9c6032c /src/runtime/sys_linux_ppc64x.s
parent6407b3c80ea7051f01615097afc60da671a688e8 (diff)
downloadgo-6fd1f825c1310e2a586a9ae0fc128a0b3c115b12.tar.gz
go-6fd1f825c1310e2a586a9ae0fc128a0b3c115b12.zip
runtime: support cgo traceback on PPC64LE
Code essentially mirrors AMD64 implementation. Change-Id: I39f7f099ce11fdc3772df039998cc11947bb22a2 Reviewed-on: https://go-review.googlesource.com/72270 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/sys_linux_ppc64x.s')
-rw-r--r--src/runtime/sys_linux_ppc64x.s101
1 files changed, 97 insertions, 4 deletions
diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s
index 100e410eec..9b45f94e65 100644
--- a/src/runtime/sys_linux_ppc64x.s
+++ b/src/runtime/sys_linux_ppc64x.s
@@ -250,7 +250,96 @@ TEXT runtime·_sigtramp(SB),NOSPLIT,$64
#ifdef GOARCH_ppc64le
// ppc64le doesn't need function descriptors
-TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
+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
+ // we save/restore LR manually.
+ MOVD LR, R10
+
+ // We're coming from C code, initialize essential registers.
+ CALL runtime·reginit(SB)
+
+ // If no traceback function, do usual sigtramp.
+ MOVD runtime·cgoTraceback(SB), R6
+ CMP $0, R6
+ BEQ sigtramp
+
+ // If no traceback support function, which means that
+ // runtime/cgo was not linked in, do usual sigtramp.
+ MOVD _cgo_callers(SB), R6
+ CMP $0, R6
+ BEQ sigtramp
+
+ // Set up g register.
+ CALL runtime·load_g(SB)
+
+ // Figure out if we are currently in a cgo call.
+ // If not, just do usual sigtramp.
+ CMP $0, g
+ BEQ sigtrampnog // g == nil
+ MOVD g_m(g), R6
+ CMP $0, R6
+ BEQ sigtramp // g.m == nil
+ MOVW m_ncgo(R6), R7
+ CMPW $0, R7
+ BEQ sigtramp // g.m.ncgo = 0
+ MOVD m_curg(R6), R7
+ CMP $0, R7
+ BEQ sigtramp // g.m.curg == nil
+ MOVD g_syscallsp(R7), R7
+ CMP $0, R7
+ BEQ sigtramp // g.m.curg.syscallsp == 0
+ MOVD m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention.
+ CMP $0, R7
+ BEQ sigtramp // g.m.cgoCallers == nil
+ MOVW m_cgoCallersUse(R6), R8
+ CMPW $0, R8
+ BNE 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), R6
+ MOVD $runtime·sigtramp(SB), R8
+ MOVD _cgo_callers(SB), R12
+ MOVD R12, CTR
+ MOVD R10, LR // restore LR
+ JMP (CTR)
+
+sigtramp:
+ MOVD R10, LR // restore LR
+ JMP runtime·sigtramp(SB)
+
+sigtrampnog:
+ // Signal arrived on a non-Go thread. If this is SIGPROF, get a
+ // stack trace.
+ CMPW R3, $27 // 27 == SIGPROF
+ BNE sigtramp
+
+ // Lock sigprofCallersUse (cas from 0 to 1).
+ MOVW $1, R7
+ MOVD $runtime·sigprofCallersUse(SB), R8
+ SYNC
+ LWAR (R8), R6
+ CMPW $0, R6
+ BNE sigtramp
+ STWCCC R7, (R8)
+ BNE -4(PC)
+ ISYNC
+
+ // 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), R6
+ MOVD $runtime·sigprofCallers(SB), R7
+ MOVD $runtime·sigprofNonGoWrapper<>(SB), R8
+ MOVD _cgo_callers(SB), R12
+ MOVD R12, CTR
+ MOVD R10, LR // restore LR
+ JMP (CTR)
#else
// function descriptor for the real sigtramp
TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
@@ -258,10 +347,14 @@ TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
DWORD $0
DWORD $0
TEXT runtime·_cgoSigtramp(SB),NOSPLIT,$0
+ JMP runtime·sigtramp(SB)
#endif
- MOVD $runtime·sigtramp(SB), R12
- MOVD R12, CTR
- JMP (CTR)
+
+TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
+ // We're coming from C code, set up essential register, then call sigprofNonGo.
+ CALL runtime·reginit(SB)
+ CALL runtime·sigprofNonGo(SB)
+ RET
TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
MOVD addr+0(FP), R3