1
0
mirror of https://github.com/golang/go synced 2024-11-23 07:40:04 -07:00

[dev.regabi] runtime: initialize special registers before sigpanic

In case that we are panicking in ABI0 context or external code,
special registers are not initialized. Initialized them in
injected code before calling sigpanic.

TODO: Windows, Plan 9.

Change-Id: I0919b80e7cc55463f3dd94f1f63cba305717270a
Reviewed-on: https://go-review.googlesource.com/c/go/+/289710
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Cherry Zhang 2021-02-04 11:41:34 -05:00
parent 5d7dc53888
commit 22f9e1ccbc
4 changed files with 26 additions and 2 deletions

View File

@ -11,3 +11,8 @@
DATA runtime·no_pointers_stackmap+0x00(SB)/4, $2
DATA runtime·no_pointers_stackmap+0x04(SB)/4, $0
GLOBL runtime·no_pointers_stackmap(SB),RODATA, $8
#ifndef GOARCH_amd64
TEXT ·sigpanic0<ABIInternal>(SB),NOSPLIT,$0-0
JMP ·sigpanic<ABIInternal>(SB)
#endif

View File

@ -1364,6 +1364,18 @@ TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
POPQ R15
RET
// Initialize special registers then jump to sigpanic.
// This function is injected from the signal handler for panicking
// signals. It is quite painful to set X15 in the signal context,
// so we do it here.
TEXT ·sigpanic0<ABIInternal>(SB),NOSPLIT,$0-0
#ifdef GOEXPERIMENT_REGABI
get_tls(R14)
MOVQ g(R14), R14
XORPS X15, X15
#endif
JMP ·sigpanic<ABIInternal>(SB)
// gcWriteBarrier performs a heap pointer write and informs the GC.
//
// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:

View File

@ -65,11 +65,14 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
pc := uintptr(c.rip())
sp := uintptr(c.rsp())
// In case we are panicking from external code, we need to initialize
// Go special registers. We inject sigpanic0 (instead of sigpanic),
// which takes care of that.
if shouldPushSigpanic(gp, pc, *(*uintptr)(unsafe.Pointer(sp))) {
c.pushCall(funcPC(sigpanic), pc)
c.pushCall(funcPC(sigpanic0), pc)
} else {
// Not safe to push the call. Just clobber the frame.
c.set_rip(uint64(funcPC(sigpanic)))
c.set_rip(uint64(funcPC(sigpanic0)))
}
}

View File

@ -356,3 +356,7 @@ func duffcopy()
// Called from linker-generated .initarray; declared for go vet; do NOT call from Go.
func addmoduledata()
// Injected by the signal handler for panicking signals. On many platforms it just
// jumps to sigpanic.
func sigpanic0()