Commit e5186895 authored by Austin Clements's avatar Austin Clements

runtime: restore RSB for sigpanic call on mips64x

preparePanic must set all registers expected by Go runtime conventions
in case the sigpanic is being injected into C code. However, on
mips64x it fails to restore RSB (R28). As a result, if C code modifies
RSB and then raises a signal that turns into a sigpanic call, sigpanic
may crash when it attempts to lock runtime.debuglock (the first global
it references).

Fix this by restoring RSB in the signal context using the same
convention as main and sigtramp.

Fixes #23641.

Change-Id: Ib47e83df89e2a3eece10f480e4e91ce9e4424388
Reviewed-on: https://go-review.googlesource.com/91156
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 3ff41cdf
......@@ -66,6 +66,7 @@ func (c *sigctxt) hi() uint64 { return c.regs().sc_mdhi }
func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr }
func (c *sigctxt) set_r28(x uint64) { c.regs().sc_regs[28] = x }
func (c *sigctxt) set_r30(x uint64) { c.regs().sc_regs[30] = x }
func (c *sigctxt) set_pc(x uint64) { c.regs().sc_pc = x }
func (c *sigctxt) set_sp(x uint64) { c.regs().sc_regs[29] = x }
......
......@@ -89,6 +89,8 @@ func (c *sigctxt) preparePanic(sig uint32, gp *g) {
}
// In case we are panicking from external C code
sigpanicPC := uint64(funcPC(sigpanic))
c.set_r28(sigpanicPC >> 32 << 32) // RSB register
c.set_r30(uint64(uintptr(unsafe.Pointer(gp))))
c.set_pc(uint64(funcPC(sigpanic)))
c.set_pc(sigpanicPC)
}
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