mirror of https://github.com/golang/go.git
runtime: support for injecting calls at signals on x86
This adds a sigctxt.pushCall method that pushes a call at the signaled site. We'll use this to inject asynchronous preemptions and in some places we use it to clean up preparePanic. For the moment this only works on 386 and amd64. We stub it out on other platforms and will avoid calling the stubbed version. For #10958, #24543. Change-Id: I49e0e853f935d32dd67a70c6cafbae44ee68af8e Reviewed-on: https://go-review.googlesource.com/c/go/+/201758 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
61fa79885b
commit
2d031dc559
|
|
@ -57,14 +57,21 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
|
|||
sp := uintptr(c.esp())
|
||||
|
||||
if shouldPushSigpanic(gp, pc, *(*uintptr)(unsafe.Pointer(sp))) {
|
||||
// Make it look like the faulting PC called sigpanic.
|
||||
if sys.RegSize > sys.PtrSize {
|
||||
sp -= sys.PtrSize
|
||||
*(*uintptr)(unsafe.Pointer(sp)) = 0
|
||||
}
|
||||
sp -= sys.PtrSize
|
||||
*(*uintptr)(unsafe.Pointer(sp)) = pc
|
||||
c.set_esp(uint32(sp))
|
||||
c.pushCall(funcPC(sigpanic))
|
||||
} else {
|
||||
// Not safe to push the call. Just clobber the frame.
|
||||
c.set_eip(uint32(funcPC(sigpanic)))
|
||||
}
|
||||
c.set_eip(uint32(funcPC(sigpanic)))
|
||||
}
|
||||
|
||||
const pushCallSupported = true
|
||||
|
||||
func (c *sigctxt) pushCall(targetPC uintptr) {
|
||||
// Make it look like the signaled instruction called target.
|
||||
pc := uintptr(c.eip())
|
||||
sp := uintptr(c.esp())
|
||||
sp -= sys.PtrSize
|
||||
*(*uintptr)(unsafe.Pointer(sp)) = pc
|
||||
c.set_esp(uint32(sp))
|
||||
c.set_eip(uint32(targetPC))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,14 +66,22 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
|
|||
sp := uintptr(c.rsp())
|
||||
|
||||
if shouldPushSigpanic(gp, pc, *(*uintptr)(unsafe.Pointer(sp))) {
|
||||
// Make it look the like faulting PC called sigpanic.
|
||||
if sys.RegSize > sys.PtrSize {
|
||||
sp -= sys.PtrSize
|
||||
*(*uintptr)(unsafe.Pointer(sp)) = 0
|
||||
}
|
||||
sp -= sys.PtrSize
|
||||
*(*uintptr)(unsafe.Pointer(sp)) = pc
|
||||
c.set_rsp(uint64(sp))
|
||||
c.pushCall(funcPC(sigpanic))
|
||||
} else {
|
||||
// Not safe to push the call. Just clobber the frame.
|
||||
c.set_rip(uint64(funcPC(sigpanic)))
|
||||
}
|
||||
c.set_rip(uint64(funcPC(sigpanic)))
|
||||
}
|
||||
|
||||
// TODO: Remove pushCallSupported once all platforms support it.
|
||||
const pushCallSupported = true
|
||||
|
||||
func (c *sigctxt) pushCall(targetPC uintptr) {
|
||||
// Make it look like the signaled instruction called target.
|
||||
pc := uintptr(c.rip())
|
||||
sp := uintptr(c.rsp())
|
||||
sp -= sys.PtrSize
|
||||
*(*uintptr)(unsafe.Pointer(sp)) = pc
|
||||
c.set_rsp(uint64(sp))
|
||||
c.set_rip(uint64(targetPC))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,3 +62,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
|
|||
c.set_r10(uint32(uintptr(unsafe.Pointer(gp))))
|
||||
c.set_pc(uint32(funcPC(sigpanic)))
|
||||
}
|
||||
|
||||
const pushCallSupported = false
|
||||
|
||||
func (c *sigctxt) pushCall(targetPC uintptr) {
|
||||
throw("not implemented")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,3 +78,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
|
|||
c.set_r28(uint64(uintptr(unsafe.Pointer(gp))))
|
||||
c.set_pc(uint64(funcPC(sigpanic)))
|
||||
}
|
||||
|
||||
const pushCallSupported = false
|
||||
|
||||
func (c *sigctxt) pushCall(targetPC uintptr) {
|
||||
throw("not implemented")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,3 +109,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
|
|||
c.set_r13(uint64(uintptr(unsafe.Pointer(gp))))
|
||||
c.set_pc(uint64(funcPC(sigpanic)))
|
||||
}
|
||||
|
||||
const pushCallSupported = false
|
||||
|
||||
func (c *sigctxt) pushCall(targetPC uintptr) {
|
||||
throw("not implemented")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,3 +84,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
|
|||
c.set_r30(uint64(uintptr(unsafe.Pointer(gp))))
|
||||
c.set_pc(sigpanicPC)
|
||||
}
|
||||
|
||||
const pushCallSupported = false
|
||||
|
||||
func (c *sigctxt) pushCall(targetPC uintptr) {
|
||||
throw("not implemented")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,3 +79,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
|
|||
c.set_r30(uint32(uintptr(unsafe.Pointer(gp))))
|
||||
c.set_pc(uint32(funcPC(sigpanic)))
|
||||
}
|
||||
|
||||
const pushCallSupported = false
|
||||
|
||||
func (c *sigctxt) pushCall(targetPC uintptr) {
|
||||
throw("not implemented")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,3 +85,9 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
|
|||
c.set_r12(uint64(funcPC(sigpanic)))
|
||||
c.set_pc(uint64(funcPC(sigpanic)))
|
||||
}
|
||||
|
||||
const pushCallSupported = false
|
||||
|
||||
func (c *sigctxt) pushCall(targetPC uintptr) {
|
||||
throw("not implemented")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue