Commit 2d031dc5 authored by Austin Clements's avatar Austin Clements

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: default avatarCherry Zhang <cherryyz@google.com>
parent 61fa7988
......@@ -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")
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment