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:
parent
5d7dc53888
commit
22f9e1ccbc
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user