mirror of
https://github.com/golang/go
synced 2024-11-24 14:20:13 -07:00
runtime: signal handling support for plan9_arm
Plan 9 trap/signal handling differs on ARM from other architectures because ARM has a link register. Also trap message syntax varies between different architectures (historical accident?). Revised 7 March to clarify a comment. Change-Id: Ib6485f82857a2f9a0d6b2c375cf0aaa230b83656 Reviewed-on: https://go-review.googlesource.com/18969 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
c97ddf9c10
commit
d145456b16
@ -30,9 +30,13 @@ type sigctxt struct {
|
|||||||
|
|
||||||
func (c *sigctxt) pc() uintptr { return uintptr(c.u.pc) }
|
func (c *sigctxt) pc() uintptr { return uintptr(c.u.pc) }
|
||||||
func (c *sigctxt) sp() uintptr { return uintptr(c.u.sp) }
|
func (c *sigctxt) sp() uintptr { return uintptr(c.u.sp) }
|
||||||
|
func (c *sigctxt) lr() uintptr { return uintptr(0) }
|
||||||
|
|
||||||
func (c *sigctxt) setpc(x uintptr) { c.u.pc = uint32(x) }
|
func (c *sigctxt) setpc(x uintptr) { c.u.pc = uint32(x) }
|
||||||
func (c *sigctxt) setsp(x uintptr) { c.u.sp = uint32(x) }
|
func (c *sigctxt) setsp(x uintptr) { c.u.sp = uint32(x) }
|
||||||
|
func (c *sigctxt) setlr(x uintptr) {}
|
||||||
|
|
||||||
|
func (c *sigctxt) savelr(x uintptr) {}
|
||||||
|
|
||||||
func dumpregs(u *ureg) {
|
func dumpregs(u *ureg) {
|
||||||
print("ax ", hex(u.ax), "\n")
|
print("ax ", hex(u.ax), "\n")
|
||||||
@ -49,3 +53,5 @@ func dumpregs(u *ureg) {
|
|||||||
print("fs ", hex(u.fs), "\n")
|
print("fs ", hex(u.fs), "\n")
|
||||||
print("gs ", hex(u.gs), "\n")
|
print("gs ", hex(u.gs), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sigpanictramp() {}
|
||||||
|
@ -39,9 +39,13 @@ type sigctxt struct {
|
|||||||
|
|
||||||
func (c *sigctxt) pc() uintptr { return uintptr(c.u.ip) }
|
func (c *sigctxt) pc() uintptr { return uintptr(c.u.ip) }
|
||||||
func (c *sigctxt) sp() uintptr { return uintptr(c.u.sp) }
|
func (c *sigctxt) sp() uintptr { return uintptr(c.u.sp) }
|
||||||
|
func (c *sigctxt) lr() uintptr { return uintptr(0) }
|
||||||
|
|
||||||
func (c *sigctxt) setpc(x uintptr) { c.u.ip = uint64(x) }
|
func (c *sigctxt) setpc(x uintptr) { c.u.ip = uint64(x) }
|
||||||
func (c *sigctxt) setsp(x uintptr) { c.u.sp = uint64(x) }
|
func (c *sigctxt) setsp(x uintptr) { c.u.sp = uint64(x) }
|
||||||
|
func (c *sigctxt) setlr(x uintptr) {}
|
||||||
|
|
||||||
|
func (c *sigctxt) savelr(x uintptr) {}
|
||||||
|
|
||||||
func dumpregs(u *ureg) {
|
func dumpregs(u *ureg) {
|
||||||
print("ax ", hex(u.ax), "\n")
|
print("ax ", hex(u.ax), "\n")
|
||||||
@ -66,3 +70,5 @@ func dumpregs(u *ureg) {
|
|||||||
print("fs ", hex(u.fs), "\n")
|
print("fs ", hex(u.fs), "\n")
|
||||||
print("gs ", hex(u.gs), "\n")
|
print("gs ", hex(u.gs), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sigpanictramp() {}
|
||||||
|
@ -66,22 +66,37 @@ func sighandler(_ureg *ureg, note *byte, gp *g) int {
|
|||||||
pc = 0
|
pc = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only push sigpanic if PC != 0.
|
// IF LR exists, sigpanictramp must save it to the stack
|
||||||
//
|
// before entry to sigpanic so that panics in leaf
|
||||||
|
// functions are correctly handled. This will smash
|
||||||
|
// the stack frame but we're not going back there
|
||||||
|
// anyway.
|
||||||
|
if usesLR {
|
||||||
|
c.savelr(c.lr())
|
||||||
|
}
|
||||||
|
|
||||||
// If PC == 0, probably panicked because of a call to a nil func.
|
// If PC == 0, probably panicked because of a call to a nil func.
|
||||||
// Not pushing that onto SP will make the trace look like a call
|
// Not faking that as the return address will make the trace look like a call
|
||||||
// to sigpanic instead. (Otherwise the trace will end at
|
// to sigpanic instead. (Otherwise the trace will end at
|
||||||
// sigpanic and we won't get to see who faulted).
|
// sigpanic and we won't get to see who faulted).
|
||||||
if pc != 0 {
|
if pc != 0 {
|
||||||
if sys.RegSize > sys.PtrSize {
|
if usesLR {
|
||||||
|
c.setlr(pc)
|
||||||
|
} else {
|
||||||
|
if sys.RegSize > sys.PtrSize {
|
||||||
|
sp -= sys.PtrSize
|
||||||
|
*(*uintptr)(unsafe.Pointer(sp)) = 0
|
||||||
|
}
|
||||||
sp -= sys.PtrSize
|
sp -= sys.PtrSize
|
||||||
*(*uintptr)(unsafe.Pointer(sp)) = 0
|
*(*uintptr)(unsafe.Pointer(sp)) = pc
|
||||||
|
c.setsp(sp)
|
||||||
}
|
}
|
||||||
sp -= sys.PtrSize
|
|
||||||
*(*uintptr)(unsafe.Pointer(sp)) = pc
|
|
||||||
c.setsp(sp)
|
|
||||||
}
|
}
|
||||||
c.setpc(funcPC(sigpanic))
|
if usesLR {
|
||||||
|
c.setpc(funcPC(sigpanictramp))
|
||||||
|
} else {
|
||||||
|
c.setpc(funcPC(sigpanic))
|
||||||
|
}
|
||||||
return _NCONT
|
return _NCONT
|
||||||
}
|
}
|
||||||
if flags&_SigNotify != 0 {
|
if flags&_SigNotify != 0 {
|
||||||
@ -105,7 +120,7 @@ Throw:
|
|||||||
level, _, docrash = gotraceback()
|
level, _, docrash = gotraceback()
|
||||||
if level > 0 {
|
if level > 0 {
|
||||||
goroutineheader(gp)
|
goroutineheader(gp)
|
||||||
tracebacktrap(c.pc(), c.sp(), 0, gp)
|
tracebacktrap(c.pc(), c.sp(), c.lr(), gp)
|
||||||
tracebackothers(gp)
|
tracebackothers(gp)
|
||||||
print("\n")
|
print("\n")
|
||||||
dumpregs(_ureg)
|
dumpregs(_ureg)
|
||||||
|
@ -78,7 +78,15 @@ func sigpanic() {
|
|||||||
note := gostringnocopy((*byte)(unsafe.Pointer(g.m.notesig)))
|
note := gostringnocopy((*byte)(unsafe.Pointer(g.m.notesig)))
|
||||||
switch g.sig {
|
switch g.sig {
|
||||||
case _SIGRFAULT, _SIGWFAULT:
|
case _SIGRFAULT, _SIGWFAULT:
|
||||||
addr := note[index(note, "addr=")+5:]
|
i := index(note, "addr=")
|
||||||
|
if i >= 0 {
|
||||||
|
i += 5
|
||||||
|
} else if i = index(note, "va="); i >= 0 {
|
||||||
|
i += 3
|
||||||
|
} else {
|
||||||
|
panicmem()
|
||||||
|
}
|
||||||
|
addr := note[i:]
|
||||||
g.sigcode1 = uintptr(atolwhex(addr))
|
g.sigcode1 = uintptr(atolwhex(addr))
|
||||||
if g.sigcode1 < 0x1000 || g.paniconfault {
|
if g.sigcode1 < 0x1000 || g.paniconfault {
|
||||||
panicmem()
|
panicmem()
|
||||||
|
@ -22,8 +22,8 @@ var sigtable = [...]sigTabT{
|
|||||||
{_SigThrow, "sys: trap: invalid opcode"},
|
{_SigThrow, "sys: trap: invalid opcode"},
|
||||||
|
|
||||||
// We can recover from some memory errors in runtime·sigpanic.
|
// We can recover from some memory errors in runtime·sigpanic.
|
||||||
{_SigPanic, "sys: trap: fault read addr"}, // SIGRFAULT
|
{_SigPanic, "sys: trap: fault read"}, // SIGRFAULT
|
||||||
{_SigPanic, "sys: trap: fault write addr"}, // SIGWFAULT
|
{_SigPanic, "sys: trap: fault write"}, // SIGWFAULT
|
||||||
|
|
||||||
// We can also recover from math errors.
|
// We can also recover from math errors.
|
||||||
{_SigPanic, "sys: trap: divide error"}, // SIGINTDIV
|
{_SigPanic, "sys: trap: divide error"}, // SIGINTDIV
|
||||||
|
Loading…
Reference in New Issue
Block a user