Commit d03e8b22 authored by Ian Lance Taylor's avatar Ian Lance Taylor

runtime: record current PC for SIGPROF on non-Go thread

If we get a SIGPROF on a non-Go thread, and the program has not called
runtime.SetCgoTraceback so we have no way to collect a stack trace, then
record a profile that is just the PC where the signal occurred. That
will at least point the user to the right area.

Retrieving the PC from the sigctxt in a signal handler on a non-G thread
required marking a number of trivial sigctxt methods as nosplit, and,
for extra safety, nowritebarrierrec.

The test shows that the existing test CgoPprofThread test does not test
the stack trace, just the profile signal. Leaving that for later.

Change-Id: I8f8f3ff09ac099fc9d9df94b5a9d210ffc20c4ab
Reviewed-on: https://go-review.googlesource.com/30252
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarDmitry Vyukov <dvyukov@google.com>
parent c24cc400
...@@ -311,6 +311,10 @@ func TestCgoPprofThread(t *testing.T) { ...@@ -311,6 +311,10 @@ func TestCgoPprofThread(t *testing.T) {
testCgoPprof(t, "", "CgoPprofThread") testCgoPprof(t, "", "CgoPprofThread")
} }
func TestCgoPprofThreadNoTraceback(t *testing.T) {
testCgoPprof(t, "", "CgoPprofThreadNoTraceback")
}
func TestRaceProf(t *testing.T) { func TestRaceProf(t *testing.T) {
if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
......
...@@ -28,7 +28,10 @@ type sigctxt struct { ...@@ -28,7 +28,10 @@ type sigctxt struct {
u *ureg u *ureg
} }
//go:nosplit
//go:nowritebarrierrec
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) lr() uintptr { return uintptr(0) }
......
...@@ -37,7 +37,10 @@ type sigctxt struct { ...@@ -37,7 +37,10 @@ type sigctxt struct {
u *ureg u *ureg
} }
//go:nosplit
//go:nowritebarrierrec
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) lr() uintptr { return uintptr(0) }
......
...@@ -31,7 +31,10 @@ type sigctxt struct { ...@@ -31,7 +31,10 @@ type sigctxt struct {
u *ureg u *ureg
} }
//go:nosplit
//go:nowritebarrierrec
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(c.u.link) } func (c *sigctxt) lr() uintptr { return uintptr(c.u.link) }
......
...@@ -3194,7 +3194,8 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) { ...@@ -3194,7 +3194,8 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
var sigprofCallers cgoCallers var sigprofCallers cgoCallers
var sigprofCallersUse uint32 var sigprofCallersUse uint32
// Called if we receive a SIGPROF signal on a non-Go thread. // sigprofNonGo is called if we receive a SIGPROF signal on a non-Go thread,
// and the signal handler collected a stack trace in sigprofCallers.
// When this is called, sigprofCallersUse will be non-zero. // When this is called, sigprofCallersUse will be non-zero.
// g is nil, and what we can do is very limited. // g is nil, and what we can do is very limited.
//go:nosplit //go:nosplit
...@@ -3207,17 +3208,41 @@ func sigprofNonGo() { ...@@ -3207,17 +3208,41 @@ func sigprofNonGo() {
} }
// Simple cas-lock to coordinate with setcpuprofilerate. // Simple cas-lock to coordinate with setcpuprofilerate.
if atomic.Cas(&prof.lock, 0, 1) { for !atomic.Cas(&prof.lock, 0, 1) {
osyield()
}
if prof.hz != 0 { if prof.hz != 0 {
cpuprof.addNonGo(sigprofCallers[:n]) cpuprof.addNonGo(sigprofCallers[:n])
} }
atomic.Store(&prof.lock, 0) atomic.Store(&prof.lock, 0)
} }
}
atomic.Store(&sigprofCallersUse, 0) atomic.Store(&sigprofCallersUse, 0)
} }
// sigprofNonGoPC is called when a profiling signal arrived on a
// non-Go thread and we have a single PC value, not a stack trace.
// g is nil, and what we can do is very limited.
//go:nosplit
//go:nowritebarrierrec
func sigprofNonGoPC(pc uintptr) {
if prof.hz != 0 {
pc := []uintptr{
pc,
funcPC(_ExternalCode) + sys.PCQuantum,
}
// Simple cas-lock to coordinate with setcpuprofilerate.
for !atomic.Cas(&prof.lock, 0, 1) {
osyield()
}
if prof.hz != 0 {
cpuprof.addNonGo(pc)
}
atomic.Store(&prof.lock, 0)
}
}
// Reports whether a function will set the SP // Reports whether a function will set the SP
// to an absolute value. Important that // to an absolute value. Important that
// we don't traceback when these are at the bottom // we don't traceback when these are at the bottom
......
...@@ -27,7 +27,10 @@ func dumpregs(c *sigctxt) { ...@@ -27,7 +27,10 @@ func dumpregs(c *sigctxt) {
print("gs ", hex(c.gs()), "\n") print("gs ", hex(c.gs()), "\n")
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) sigpc() uintptr { return uintptr(c.eip()) } func (c *sigctxt) sigpc() uintptr { return uintptr(c.eip()) }
func (c *sigctxt) sigsp() uintptr { return uintptr(c.esp()) } func (c *sigctxt) sigsp() uintptr { return uintptr(c.esp()) }
func (c *sigctxt) siglr() uintptr { return 0 } func (c *sigctxt) siglr() uintptr { return 0 }
func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) } func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) }
......
...@@ -36,7 +36,10 @@ func dumpregs(c *sigctxt) { ...@@ -36,7 +36,10 @@ func dumpregs(c *sigctxt) {
print("gs ", hex(c.gs()), "\n") print("gs ", hex(c.gs()), "\n")
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) sigpc() uintptr { return uintptr(c.rip()) } func (c *sigctxt) sigpc() uintptr { return uintptr(c.rip()) }
func (c *sigctxt) sigsp() uintptr { return uintptr(c.rsp()) } func (c *sigctxt) sigsp() uintptr { return uintptr(c.rsp()) }
func (c *sigctxt) siglr() uintptr { return 0 } func (c *sigctxt) siglr() uintptr { return 0 }
func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) } func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) }
......
...@@ -32,7 +32,10 @@ func dumpregs(c *sigctxt) { ...@@ -32,7 +32,10 @@ func dumpregs(c *sigctxt) {
print("fault ", hex(c.fault()), "\n") print("fault ", hex(c.fault()), "\n")
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) } func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) }
func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) } func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) }
func (c *sigctxt) siglr() uintptr { return uintptr(c.lr()) } func (c *sigctxt) siglr() uintptr { return uintptr(c.lr()) }
......
...@@ -48,7 +48,10 @@ func dumpregs(c *sigctxt) { ...@@ -48,7 +48,10 @@ func dumpregs(c *sigctxt) {
print("fault ", hex(c.fault()), "\n") print("fault ", hex(c.fault()), "\n")
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) } func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) }
func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) } func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) }
func (c *sigctxt) siglr() uintptr { return uintptr(c.lr()) } func (c *sigctxt) siglr() uintptr { return uintptr(c.lr()) }
......
...@@ -11,7 +11,10 @@ type sigctxt struct { ...@@ -11,7 +11,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *regs32 { return &(*ucontext)(c.ctxt).uc_mcontext.ss } func (c *sigctxt) regs() *regs32 { return &(*ucontext)(c.ctxt).uc_mcontext.ss }
func (c *sigctxt) eax() uint32 { return c.regs().eax } func (c *sigctxt) eax() uint32 { return c.regs().eax }
func (c *sigctxt) ebx() uint32 { return c.regs().ebx } func (c *sigctxt) ebx() uint32 { return c.regs().ebx }
func (c *sigctxt) ecx() uint32 { return c.regs().ecx } func (c *sigctxt) ecx() uint32 { return c.regs().ecx }
...@@ -20,7 +23,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().edi } ...@@ -20,7 +23,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().edi }
func (c *sigctxt) esi() uint32 { return c.regs().esi } func (c *sigctxt) esi() uint32 { return c.regs().esi }
func (c *sigctxt) ebp() uint32 { return c.regs().ebp } func (c *sigctxt) ebp() uint32 { return c.regs().ebp }
func (c *sigctxt) esp() uint32 { return c.regs().esp } func (c *sigctxt) esp() uint32 { return c.regs().esp }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) eip() uint32 { return c.regs().eip } func (c *sigctxt) eip() uint32 { return c.regs().eip }
func (c *sigctxt) eflags() uint32 { return c.regs().eflags } func (c *sigctxt) eflags() uint32 { return c.regs().eflags }
func (c *sigctxt) cs() uint32 { return c.regs().cs } func (c *sigctxt) cs() uint32 { return c.regs().cs }
func (c *sigctxt) fs() uint32 { return c.regs().fs } func (c *sigctxt) fs() uint32 { return c.regs().fs }
......
...@@ -11,7 +11,10 @@ type sigctxt struct { ...@@ -11,7 +11,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *regs64 { return &(*ucontext)(c.ctxt).uc_mcontext.ss } func (c *sigctxt) regs() *regs64 { return &(*ucontext)(c.ctxt).uc_mcontext.ss }
func (c *sigctxt) rax() uint64 { return c.regs().rax } func (c *sigctxt) rax() uint64 { return c.regs().rax }
func (c *sigctxt) rbx() uint64 { return c.regs().rbx } func (c *sigctxt) rbx() uint64 { return c.regs().rbx }
func (c *sigctxt) rcx() uint64 { return c.regs().rcx } func (c *sigctxt) rcx() uint64 { return c.regs().rcx }
...@@ -28,7 +31,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().r12 } ...@@ -28,7 +31,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().r12 }
func (c *sigctxt) r13() uint64 { return c.regs().r13 } func (c *sigctxt) r13() uint64 { return c.regs().r13 }
func (c *sigctxt) r14() uint64 { return c.regs().r14 } func (c *sigctxt) r14() uint64 { return c.regs().r14 }
func (c *sigctxt) r15() uint64 { return c.regs().r15 } func (c *sigctxt) r15() uint64 { return c.regs().r15 }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) rip() uint64 { return c.regs().rip } func (c *sigctxt) rip() uint64 { return c.regs().rip }
func (c *sigctxt) rflags() uint64 { return c.regs().rflags } func (c *sigctxt) rflags() uint64 { return c.regs().rflags }
func (c *sigctxt) cs() uint64 { return c.regs().cs } func (c *sigctxt) cs() uint64 { return c.regs().cs }
func (c *sigctxt) fs() uint64 { return c.regs().fs } func (c *sigctxt) fs() uint64 { return c.regs().fs }
......
...@@ -11,7 +11,10 @@ type sigctxt struct { ...@@ -11,7 +11,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *regs32 { return &(*ucontext)(c.ctxt).uc_mcontext.ss } func (c *sigctxt) regs() *regs32 { return &(*ucontext)(c.ctxt).uc_mcontext.ss }
func (c *sigctxt) r0() uint32 { return c.regs().r[0] } func (c *sigctxt) r0() uint32 { return c.regs().r[0] }
func (c *sigctxt) r1() uint32 { return c.regs().r[1] } func (c *sigctxt) r1() uint32 { return c.regs().r[1] }
func (c *sigctxt) r2() uint32 { return c.regs().r[2] } func (c *sigctxt) r2() uint32 { return c.regs().r[2] }
...@@ -27,7 +30,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().r[11] } ...@@ -27,7 +30,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().r[11] }
func (c *sigctxt) ip() uint32 { return c.regs().r[12] } func (c *sigctxt) ip() uint32 { return c.regs().r[12] }
func (c *sigctxt) sp() uint32 { return c.regs().sp } func (c *sigctxt) sp() uint32 { return c.regs().sp }
func (c *sigctxt) lr() uint32 { return c.regs().lr } func (c *sigctxt) lr() uint32 { return c.regs().lr }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint32 { return c.regs().pc } func (c *sigctxt) pc() uint32 { return c.regs().pc }
func (c *sigctxt) cpsr() uint32 { return c.regs().cpsr } func (c *sigctxt) cpsr() uint32 { return c.regs().cpsr }
func (c *sigctxt) fault() uint32 { return c.info.si_addr } func (c *sigctxt) fault() uint32 { return c.info.si_addr }
func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) } func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
......
...@@ -11,7 +11,10 @@ type sigctxt struct { ...@@ -11,7 +11,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *regs64 { return &(*ucontext)(c.ctxt).uc_mcontext.ss } func (c *sigctxt) regs() *regs64 { return &(*ucontext)(c.ctxt).uc_mcontext.ss }
func (c *sigctxt) r0() uint64 { return c.regs().x[0] } func (c *sigctxt) r0() uint64 { return c.regs().x[0] }
func (c *sigctxt) r1() uint64 { return c.regs().x[1] } func (c *sigctxt) r1() uint64 { return c.regs().x[1] }
func (c *sigctxt) r2() uint64 { return c.regs().x[2] } func (c *sigctxt) r2() uint64 { return c.regs().x[2] }
...@@ -44,7 +47,11 @@ func (c *sigctxt) r28() uint64 { return c.regs().x[28] } ...@@ -44,7 +47,11 @@ func (c *sigctxt) r28() uint64 { return c.regs().x[28] }
func (c *sigctxt) r29() uint64 { return c.regs().fp } func (c *sigctxt) r29() uint64 { return c.regs().fp }
func (c *sigctxt) lr() uint64 { return c.regs().lr } func (c *sigctxt) lr() uint64 { return c.regs().lr }
func (c *sigctxt) sp() uint64 { return c.regs().sp } func (c *sigctxt) sp() uint64 { return c.regs().sp }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint64 { return c.regs().pc } func (c *sigctxt) pc() uint64 { return c.regs().pc }
func (c *sigctxt) fault() uint64 { return uint64(uintptr(unsafe.Pointer(c.info.si_addr))) } func (c *sigctxt) fault() uint64 { return uint64(uintptr(unsafe.Pointer(c.info.si_addr))) }
func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) } func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
......
...@@ -11,9 +11,12 @@ type sigctxt struct { ...@@ -11,9 +11,12 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontext { func (c *sigctxt) regs() *mcontext {
return (*mcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext)) return (*mcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext))
} }
func (c *sigctxt) rax() uint64 { return c.regs().mc_rax } func (c *sigctxt) rax() uint64 { return c.regs().mc_rax }
func (c *sigctxt) rbx() uint64 { return c.regs().mc_rbx } func (c *sigctxt) rbx() uint64 { return c.regs().mc_rbx }
func (c *sigctxt) rcx() uint64 { return c.regs().mc_rcx } func (c *sigctxt) rcx() uint64 { return c.regs().mc_rcx }
...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().mc_r12 } ...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().mc_r12 }
func (c *sigctxt) r13() uint64 { return c.regs().mc_r13 } func (c *sigctxt) r13() uint64 { return c.regs().mc_r13 }
func (c *sigctxt) r14() uint64 { return c.regs().mc_r14 } func (c *sigctxt) r14() uint64 { return c.regs().mc_r14 }
func (c *sigctxt) r15() uint64 { return c.regs().mc_r15 } func (c *sigctxt) r15() uint64 { return c.regs().mc_r15 }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) rip() uint64 { return c.regs().mc_rip } func (c *sigctxt) rip() uint64 { return c.regs().mc_rip }
func (c *sigctxt) rflags() uint64 { return c.regs().mc_rflags } func (c *sigctxt) rflags() uint64 { return c.regs().mc_rflags }
func (c *sigctxt) cs() uint64 { return c.regs().mc_cs } func (c *sigctxt) cs() uint64 { return c.regs().mc_cs }
func (c *sigctxt) fs() uint64 { return c.regs().mc_ss } func (c *sigctxt) fs() uint64 { return c.regs().mc_ss }
......
...@@ -11,7 +11,10 @@ type sigctxt struct { ...@@ -11,7 +11,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontext { return &(*ucontext)(c.ctxt).uc_mcontext } func (c *sigctxt) regs() *mcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
func (c *sigctxt) eax() uint32 { return c.regs().mc_eax } func (c *sigctxt) eax() uint32 { return c.regs().mc_eax }
func (c *sigctxt) ebx() uint32 { return c.regs().mc_ebx } func (c *sigctxt) ebx() uint32 { return c.regs().mc_ebx }
func (c *sigctxt) ecx() uint32 { return c.regs().mc_ecx } func (c *sigctxt) ecx() uint32 { return c.regs().mc_ecx }
...@@ -20,7 +23,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().mc_edi } ...@@ -20,7 +23,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().mc_edi }
func (c *sigctxt) esi() uint32 { return c.regs().mc_esi } func (c *sigctxt) esi() uint32 { return c.regs().mc_esi }
func (c *sigctxt) ebp() uint32 { return c.regs().mc_ebp } func (c *sigctxt) ebp() uint32 { return c.regs().mc_ebp }
func (c *sigctxt) esp() uint32 { return c.regs().mc_esp } func (c *sigctxt) esp() uint32 { return c.regs().mc_esp }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) eip() uint32 { return c.regs().mc_eip } func (c *sigctxt) eip() uint32 { return c.regs().mc_eip }
func (c *sigctxt) eflags() uint32 { return c.regs().mc_eflags } func (c *sigctxt) eflags() uint32 { return c.regs().mc_eflags }
func (c *sigctxt) cs() uint32 { return c.regs().mc_cs } func (c *sigctxt) cs() uint32 { return c.regs().mc_cs }
func (c *sigctxt) fs() uint32 { return c.regs().mc_fs } func (c *sigctxt) fs() uint32 { return c.regs().mc_fs }
......
...@@ -11,9 +11,12 @@ type sigctxt struct { ...@@ -11,9 +11,12 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontext { func (c *sigctxt) regs() *mcontext {
return (*mcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext)) return (*mcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext))
} }
func (c *sigctxt) rax() uint64 { return c.regs().mc_rax } func (c *sigctxt) rax() uint64 { return c.regs().mc_rax }
func (c *sigctxt) rbx() uint64 { return c.regs().mc_rbx } func (c *sigctxt) rbx() uint64 { return c.regs().mc_rbx }
func (c *sigctxt) rcx() uint64 { return c.regs().mc_rcx } func (c *sigctxt) rcx() uint64 { return c.regs().mc_rcx }
...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().mc_r12 } ...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().mc_r12 }
func (c *sigctxt) r13() uint64 { return c.regs().mc_r13 } func (c *sigctxt) r13() uint64 { return c.regs().mc_r13 }
func (c *sigctxt) r14() uint64 { return c.regs().mc_r14 } func (c *sigctxt) r14() uint64 { return c.regs().mc_r14 }
func (c *sigctxt) r15() uint64 { return c.regs().mc_r15 } func (c *sigctxt) r15() uint64 { return c.regs().mc_r15 }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) rip() uint64 { return c.regs().mc_rip } func (c *sigctxt) rip() uint64 { return c.regs().mc_rip }
func (c *sigctxt) rflags() uint64 { return c.regs().mc_rflags } func (c *sigctxt) rflags() uint64 { return c.regs().mc_rflags }
func (c *sigctxt) cs() uint64 { return c.regs().mc_cs } func (c *sigctxt) cs() uint64 { return c.regs().mc_cs }
func (c *sigctxt) fs() uint64 { return uint64(c.regs().mc_fs) } func (c *sigctxt) fs() uint64 { return uint64(c.regs().mc_fs) }
......
...@@ -11,7 +11,10 @@ type sigctxt struct { ...@@ -11,7 +11,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontext { return &(*ucontext)(c.ctxt).uc_mcontext } func (c *sigctxt) regs() *mcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
func (c *sigctxt) r0() uint32 { return c.regs().__gregs[0] } func (c *sigctxt) r0() uint32 { return c.regs().__gregs[0] }
func (c *sigctxt) r1() uint32 { return c.regs().__gregs[1] } func (c *sigctxt) r1() uint32 { return c.regs().__gregs[1] }
func (c *sigctxt) r2() uint32 { return c.regs().__gregs[2] } func (c *sigctxt) r2() uint32 { return c.regs().__gregs[2] }
...@@ -27,7 +30,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().__gregs[11] } ...@@ -27,7 +30,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().__gregs[11] }
func (c *sigctxt) ip() uint32 { return c.regs().__gregs[12] } func (c *sigctxt) ip() uint32 { return c.regs().__gregs[12] }
func (c *sigctxt) sp() uint32 { return c.regs().__gregs[13] } func (c *sigctxt) sp() uint32 { return c.regs().__gregs[13] }
func (c *sigctxt) lr() uint32 { return c.regs().__gregs[14] } func (c *sigctxt) lr() uint32 { return c.regs().__gregs[14] }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint32 { return c.regs().__gregs[15] } func (c *sigctxt) pc() uint32 { return c.regs().__gregs[15] }
func (c *sigctxt) cpsr() uint32 { return c.regs().__gregs[16] } func (c *sigctxt) cpsr() uint32 { return c.regs().__gregs[16] }
func (c *sigctxt) fault() uint32 { return uint32(c.info.si_addr) } func (c *sigctxt) fault() uint32 { return uint32(c.info.si_addr) }
func (c *sigctxt) trap() uint32 { return 0 } func (c *sigctxt) trap() uint32 { return 0 }
......
...@@ -14,7 +14,10 @@ type sigctxt struct { ...@@ -14,7 +14,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext } func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
func (c *sigctxt) eax() uint32 { return c.regs().eax } func (c *sigctxt) eax() uint32 { return c.regs().eax }
func (c *sigctxt) ebx() uint32 { return c.regs().ebx } func (c *sigctxt) ebx() uint32 { return c.regs().ebx }
func (c *sigctxt) ecx() uint32 { return c.regs().ecx } func (c *sigctxt) ecx() uint32 { return c.regs().ecx }
...@@ -23,7 +26,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().edi } ...@@ -23,7 +26,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().edi }
func (c *sigctxt) esi() uint32 { return c.regs().esi } func (c *sigctxt) esi() uint32 { return c.regs().esi }
func (c *sigctxt) ebp() uint32 { return c.regs().ebp } func (c *sigctxt) ebp() uint32 { return c.regs().ebp }
func (c *sigctxt) esp() uint32 { return c.regs().esp } func (c *sigctxt) esp() uint32 { return c.regs().esp }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) eip() uint32 { return c.regs().eip } func (c *sigctxt) eip() uint32 { return c.regs().eip }
func (c *sigctxt) eflags() uint32 { return c.regs().eflags } func (c *sigctxt) eflags() uint32 { return c.regs().eflags }
func (c *sigctxt) cs() uint32 { return uint32(c.regs().cs) } func (c *sigctxt) cs() uint32 { return uint32(c.regs().cs) }
func (c *sigctxt) fs() uint32 { return uint32(c.regs().fs) } func (c *sigctxt) fs() uint32 { return uint32(c.regs().fs) }
......
...@@ -14,9 +14,12 @@ type sigctxt struct { ...@@ -14,9 +14,12 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext { func (c *sigctxt) regs() *sigcontext {
return (*sigcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext)) return (*sigcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext))
} }
func (c *sigctxt) rax() uint64 { return c.regs().rax } func (c *sigctxt) rax() uint64 { return c.regs().rax }
func (c *sigctxt) rbx() uint64 { return c.regs().rbx } func (c *sigctxt) rbx() uint64 { return c.regs().rbx }
func (c *sigctxt) rcx() uint64 { return c.regs().rcx } func (c *sigctxt) rcx() uint64 { return c.regs().rcx }
...@@ -33,7 +36,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().r12 } ...@@ -33,7 +36,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().r12 }
func (c *sigctxt) r13() uint64 { return c.regs().r13 } func (c *sigctxt) r13() uint64 { return c.regs().r13 }
func (c *sigctxt) r14() uint64 { return c.regs().r14 } func (c *sigctxt) r14() uint64 { return c.regs().r14 }
func (c *sigctxt) r15() uint64 { return c.regs().r15 } func (c *sigctxt) r15() uint64 { return c.regs().r15 }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) rip() uint64 { return c.regs().rip } func (c *sigctxt) rip() uint64 { return c.regs().rip }
func (c *sigctxt) rflags() uint64 { return c.regs().eflags } func (c *sigctxt) rflags() uint64 { return c.regs().eflags }
func (c *sigctxt) cs() uint64 { return uint64(c.regs().cs) } func (c *sigctxt) cs() uint64 { return uint64(c.regs().cs) }
func (c *sigctxt) fs() uint64 { return uint64(c.regs().fs) } func (c *sigctxt) fs() uint64 { return uint64(c.regs().fs) }
......
...@@ -14,7 +14,10 @@ type sigctxt struct { ...@@ -14,7 +14,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext } func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
func (c *sigctxt) r0() uint32 { return c.regs().r0 } func (c *sigctxt) r0() uint32 { return c.regs().r0 }
func (c *sigctxt) r1() uint32 { return c.regs().r1 } func (c *sigctxt) r1() uint32 { return c.regs().r1 }
func (c *sigctxt) r2() uint32 { return c.regs().r2 } func (c *sigctxt) r2() uint32 { return c.regs().r2 }
...@@ -30,7 +33,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().fp } ...@@ -30,7 +33,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().fp }
func (c *sigctxt) ip() uint32 { return c.regs().ip } func (c *sigctxt) ip() uint32 { return c.regs().ip }
func (c *sigctxt) sp() uint32 { return c.regs().sp } func (c *sigctxt) sp() uint32 { return c.regs().sp }
func (c *sigctxt) lr() uint32 { return c.regs().lr } func (c *sigctxt) lr() uint32 { return c.regs().lr }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint32 { return c.regs().pc } func (c *sigctxt) pc() uint32 { return c.regs().pc }
func (c *sigctxt) cpsr() uint32 { return c.regs().cpsr } func (c *sigctxt) cpsr() uint32 { return c.regs().cpsr }
func (c *sigctxt) fault() uint32 { return c.regs().fault_address } func (c *sigctxt) fault() uint32 { return c.regs().fault_address }
func (c *sigctxt) trap() uint32 { return c.regs().trap_no } func (c *sigctxt) trap() uint32 { return c.regs().trap_no }
......
...@@ -14,7 +14,10 @@ type sigctxt struct { ...@@ -14,7 +14,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext } func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
func (c *sigctxt) r0() uint64 { return c.regs().regs[0] } func (c *sigctxt) r0() uint64 { return c.regs().regs[0] }
func (c *sigctxt) r1() uint64 { return c.regs().regs[1] } func (c *sigctxt) r1() uint64 { return c.regs().regs[1] }
func (c *sigctxt) r2() uint64 { return c.regs().regs[2] } func (c *sigctxt) r2() uint64 { return c.regs().regs[2] }
...@@ -47,7 +50,11 @@ func (c *sigctxt) r28() uint64 { return c.regs().regs[28] } ...@@ -47,7 +50,11 @@ func (c *sigctxt) r28() uint64 { return c.regs().regs[28] }
func (c *sigctxt) r29() uint64 { return c.regs().regs[29] } func (c *sigctxt) r29() uint64 { return c.regs().regs[29] }
func (c *sigctxt) lr() uint64 { return c.regs().regs[30] } func (c *sigctxt) lr() uint64 { return c.regs().regs[30] }
func (c *sigctxt) sp() uint64 { return c.regs().sp } func (c *sigctxt) sp() uint64 { return c.regs().sp }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint64 { return c.regs().pc } func (c *sigctxt) pc() uint64 { return c.regs().pc }
func (c *sigctxt) pstate() uint64 { return c.regs().pstate } func (c *sigctxt) pstate() uint64 { return c.regs().pstate }
func (c *sigctxt) fault() uint64 { return c.regs().fault_address } func (c *sigctxt) fault() uint64 { return c.regs().fault_address }
......
...@@ -17,7 +17,10 @@ type sigctxt struct { ...@@ -17,7 +17,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext } func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
func (c *sigctxt) r0() uint64 { return c.regs().sc_regs[0] } func (c *sigctxt) r0() uint64 { return c.regs().sc_regs[0] }
func (c *sigctxt) r1() uint64 { return c.regs().sc_regs[1] } func (c *sigctxt) r1() uint64 { return c.regs().sc_regs[1] }
func (c *sigctxt) r2() uint64 { return c.regs().sc_regs[2] } func (c *sigctxt) r2() uint64 { return c.regs().sc_regs[2] }
...@@ -51,7 +54,11 @@ func (c *sigctxt) r29() uint64 { return c.regs().sc_regs[29] } ...@@ -51,7 +54,11 @@ func (c *sigctxt) r29() uint64 { return c.regs().sc_regs[29] }
func (c *sigctxt) r30() uint64 { return c.regs().sc_regs[30] } func (c *sigctxt) r30() uint64 { return c.regs().sc_regs[30] }
func (c *sigctxt) r31() uint64 { return c.regs().sc_regs[31] } func (c *sigctxt) r31() uint64 { return c.regs().sc_regs[31] }
func (c *sigctxt) sp() uint64 { return c.regs().sc_regs[29] } func (c *sigctxt) sp() uint64 { return c.regs().sc_regs[29] }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint64 { return c.regs().sc_pc } func (c *sigctxt) pc() uint64 { return c.regs().sc_pc }
func (c *sigctxt) link() uint64 { return c.regs().sc_regs[31] } func (c *sigctxt) link() uint64 { return c.regs().sc_regs[31] }
func (c *sigctxt) lo() uint64 { return c.regs().sc_mdlo } func (c *sigctxt) lo() uint64 { return c.regs().sc_mdlo }
func (c *sigctxt) hi() uint64 { return c.regs().sc_mdhi } func (c *sigctxt) hi() uint64 { return c.regs().sc_mdhi }
......
...@@ -17,7 +17,10 @@ type sigctxt struct { ...@@ -17,7 +17,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *ptregs { return (*ucontext)(c.ctxt).uc_mcontext.regs } func (c *sigctxt) regs() *ptregs { return (*ucontext)(c.ctxt).uc_mcontext.regs }
func (c *sigctxt) r0() uint64 { return c.regs().gpr[0] } func (c *sigctxt) r0() uint64 { return c.regs().gpr[0] }
func (c *sigctxt) r1() uint64 { return c.regs().gpr[1] } func (c *sigctxt) r1() uint64 { return c.regs().gpr[1] }
func (c *sigctxt) r2() uint64 { return c.regs().gpr[2] } func (c *sigctxt) r2() uint64 { return c.regs().gpr[2] }
...@@ -51,7 +54,11 @@ func (c *sigctxt) r29() uint64 { return c.regs().gpr[29] } ...@@ -51,7 +54,11 @@ func (c *sigctxt) r29() uint64 { return c.regs().gpr[29] }
func (c *sigctxt) r30() uint64 { return c.regs().gpr[30] } func (c *sigctxt) r30() uint64 { return c.regs().gpr[30] }
func (c *sigctxt) r31() uint64 { return c.regs().gpr[31] } func (c *sigctxt) r31() uint64 { return c.regs().gpr[31] }
func (c *sigctxt) sp() uint64 { return c.regs().gpr[1] } func (c *sigctxt) sp() uint64 { return c.regs().gpr[1] }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint64 { return c.regs().nip } func (c *sigctxt) pc() uint64 { return c.regs().nip }
func (c *sigctxt) trap() uint64 { return c.regs().trap } func (c *sigctxt) trap() uint64 { return c.regs().trap }
func (c *sigctxt) ctr() uint64 { return c.regs().ctr } func (c *sigctxt) ctr() uint64 { return c.regs().ctr }
func (c *sigctxt) link() uint64 { return c.regs().link } func (c *sigctxt) link() uint64 { return c.regs().link }
......
...@@ -14,9 +14,12 @@ type sigctxt struct { ...@@ -14,9 +14,12 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext { func (c *sigctxt) regs() *sigcontext {
return (*sigcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext)) return (*sigcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext))
} }
func (c *sigctxt) r0() uint64 { return c.regs().gregs[0] } func (c *sigctxt) r0() uint64 { return c.regs().gregs[0] }
func (c *sigctxt) r1() uint64 { return c.regs().gregs[1] } func (c *sigctxt) r1() uint64 { return c.regs().gregs[1] }
func (c *sigctxt) r2() uint64 { return c.regs().gregs[2] } func (c *sigctxt) r2() uint64 { return c.regs().gregs[2] }
...@@ -35,7 +38,11 @@ func (c *sigctxt) r14() uint64 { return c.regs().gregs[14] } ...@@ -35,7 +38,11 @@ func (c *sigctxt) r14() uint64 { return c.regs().gregs[14] }
func (c *sigctxt) r15() uint64 { return c.regs().gregs[15] } func (c *sigctxt) r15() uint64 { return c.regs().gregs[15] }
func (c *sigctxt) link() uint64 { return c.regs().gregs[14] } func (c *sigctxt) link() uint64 { return c.regs().gregs[14] }
func (c *sigctxt) sp() uint64 { return c.regs().gregs[15] } func (c *sigctxt) sp() uint64 { return c.regs().gregs[15] }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint64 { return c.regs().psw_addr } func (c *sigctxt) pc() uint64 { return c.regs().psw_addr }
func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) } func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr } func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr }
...@@ -70,7 +77,10 @@ func dumpregs(c *sigctxt) { ...@@ -70,7 +77,10 @@ func dumpregs(c *sigctxt) {
print("link ", hex(c.link()), "\n") print("link ", hex(c.link()), "\n")
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) } func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) }
func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) } func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) }
func (c *sigctxt) siglr() uintptr { return uintptr(c.link()) } func (c *sigctxt) siglr() uintptr { return uintptr(c.link()) }
func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) } func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) }
......
...@@ -51,7 +51,10 @@ func dumpregs(c *sigctxt) { ...@@ -51,7 +51,10 @@ func dumpregs(c *sigctxt) {
print("hi ", hex(c.hi()), "\n") print("hi ", hex(c.hi()), "\n")
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) } func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) }
func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) } func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) }
func (c *sigctxt) siglr() uintptr { return uintptr(c.link()) } func (c *sigctxt) siglr() uintptr { return uintptr(c.link()) }
func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) } func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) }
......
...@@ -11,7 +11,10 @@ type sigctxt struct { ...@@ -11,7 +11,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *excregs386 { return &(*exccontext)(c.ctxt).regs } func (c *sigctxt) regs() *excregs386 { return &(*exccontext)(c.ctxt).regs }
func (c *sigctxt) eax() uint32 { return c.regs().eax } func (c *sigctxt) eax() uint32 { return c.regs().eax }
func (c *sigctxt) ebx() uint32 { return c.regs().ebx } func (c *sigctxt) ebx() uint32 { return c.regs().ebx }
func (c *sigctxt) ecx() uint32 { return c.regs().ecx } func (c *sigctxt) ecx() uint32 { return c.regs().ecx }
...@@ -20,7 +23,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().edi } ...@@ -20,7 +23,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().edi }
func (c *sigctxt) esi() uint32 { return c.regs().esi } func (c *sigctxt) esi() uint32 { return c.regs().esi }
func (c *sigctxt) ebp() uint32 { return c.regs().ebp } func (c *sigctxt) ebp() uint32 { return c.regs().ebp }
func (c *sigctxt) esp() uint32 { return c.regs().esp } func (c *sigctxt) esp() uint32 { return c.regs().esp }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) eip() uint32 { return c.regs().eip } func (c *sigctxt) eip() uint32 { return c.regs().eip }
func (c *sigctxt) eflags() uint32 { return c.regs().eflags } func (c *sigctxt) eflags() uint32 { return c.regs().eflags }
func (c *sigctxt) cs() uint32 { return ^uint32(0) } func (c *sigctxt) cs() uint32 { return ^uint32(0) }
func (c *sigctxt) fs() uint32 { return ^uint32(0) } func (c *sigctxt) fs() uint32 { return ^uint32(0) }
......
...@@ -11,9 +11,12 @@ type sigctxt struct { ...@@ -11,9 +11,12 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *excregsamd64 { func (c *sigctxt) regs() *excregsamd64 {
return &(*exccontext)(c.ctxt).regs return &(*exccontext)(c.ctxt).regs
} }
func (c *sigctxt) rax() uint64 { return c.regs().rax } func (c *sigctxt) rax() uint64 { return c.regs().rax }
func (c *sigctxt) rbx() uint64 { return c.regs().rbx } func (c *sigctxt) rbx() uint64 { return c.regs().rbx }
func (c *sigctxt) rcx() uint64 { return c.regs().rcx } func (c *sigctxt) rcx() uint64 { return c.regs().rcx }
...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().r12 } ...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().r12 }
func (c *sigctxt) r13() uint64 { return c.regs().r13 } func (c *sigctxt) r13() uint64 { return c.regs().r13 }
func (c *sigctxt) r14() uint64 { return c.regs().r14 } func (c *sigctxt) r14() uint64 { return c.regs().r14 }
func (c *sigctxt) r15() uint64 { return c.regs().r15 } func (c *sigctxt) r15() uint64 { return c.regs().r15 }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) rip() uint64 { return c.regs().rip } func (c *sigctxt) rip() uint64 { return c.regs().rip }
func (c *sigctxt) rflags() uint64 { return uint64(c.regs().rflags) } func (c *sigctxt) rflags() uint64 { return uint64(c.regs().rflags) }
func (c *sigctxt) cs() uint64 { return ^uint64(0) } func (c *sigctxt) cs() uint64 { return ^uint64(0) }
func (c *sigctxt) fs() uint64 { return ^uint64(0) } func (c *sigctxt) fs() uint64 { return ^uint64(0) }
......
...@@ -11,6 +11,8 @@ type sigctxt struct { ...@@ -11,6 +11,8 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *excregsarm { return &(*exccontext)(c.ctxt).regs } func (c *sigctxt) regs() *excregsarm { return &(*exccontext)(c.ctxt).regs }
func (c *sigctxt) r0() uint32 { return c.regs().r0 } func (c *sigctxt) r0() uint32 { return c.regs().r0 }
...@@ -28,7 +30,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().r11 } ...@@ -28,7 +30,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().r11 }
func (c *sigctxt) ip() uint32 { return c.regs().r12 } func (c *sigctxt) ip() uint32 { return c.regs().r12 }
func (c *sigctxt) sp() uint32 { return c.regs().sp } func (c *sigctxt) sp() uint32 { return c.regs().sp }
func (c *sigctxt) lr() uint32 { return c.regs().lr } func (c *sigctxt) lr() uint32 { return c.regs().lr }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint32 { return c.regs().pc } func (c *sigctxt) pc() uint32 { return c.regs().pc }
func (c *sigctxt) cpsr() uint32 { return c.regs().cpsr } func (c *sigctxt) cpsr() uint32 { return c.regs().cpsr }
func (c *sigctxt) fault() uint32 { return ^uint32(0) } func (c *sigctxt) fault() uint32 { return ^uint32(0) }
func (c *sigctxt) trap() uint32 { return ^uint32(0) } func (c *sigctxt) trap() uint32 { return ^uint32(0) }
......
...@@ -11,7 +11,10 @@ type sigctxt struct { ...@@ -11,7 +11,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontextt { return &(*ucontextt)(c.ctxt).uc_mcontext } func (c *sigctxt) regs() *mcontextt { return &(*ucontextt)(c.ctxt).uc_mcontext }
func (c *sigctxt) eax() uint32 { return c.regs().__gregs[_REG_EAX] } func (c *sigctxt) eax() uint32 { return c.regs().__gregs[_REG_EAX] }
func (c *sigctxt) ebx() uint32 { return c.regs().__gregs[_REG_EBX] } func (c *sigctxt) ebx() uint32 { return c.regs().__gregs[_REG_EBX] }
func (c *sigctxt) ecx() uint32 { return c.regs().__gregs[_REG_ECX] } func (c *sigctxt) ecx() uint32 { return c.regs().__gregs[_REG_ECX] }
...@@ -20,7 +23,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().__gregs[_REG_EDI] } ...@@ -20,7 +23,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().__gregs[_REG_EDI] }
func (c *sigctxt) esi() uint32 { return c.regs().__gregs[_REG_ESI] } func (c *sigctxt) esi() uint32 { return c.regs().__gregs[_REG_ESI] }
func (c *sigctxt) ebp() uint32 { return c.regs().__gregs[_REG_EBP] } func (c *sigctxt) ebp() uint32 { return c.regs().__gregs[_REG_EBP] }
func (c *sigctxt) esp() uint32 { return c.regs().__gregs[_REG_UESP] } func (c *sigctxt) esp() uint32 { return c.regs().__gregs[_REG_UESP] }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) eip() uint32 { return c.regs().__gregs[_REG_EIP] } func (c *sigctxt) eip() uint32 { return c.regs().__gregs[_REG_EIP] }
func (c *sigctxt) eflags() uint32 { return c.regs().__gregs[_REG_EFL] } func (c *sigctxt) eflags() uint32 { return c.regs().__gregs[_REG_EFL] }
func (c *sigctxt) cs() uint32 { return c.regs().__gregs[_REG_CS] } func (c *sigctxt) cs() uint32 { return c.regs().__gregs[_REG_CS] }
func (c *sigctxt) fs() uint32 { return c.regs().__gregs[_REG_FS] } func (c *sigctxt) fs() uint32 { return c.regs().__gregs[_REG_FS] }
......
...@@ -11,9 +11,12 @@ type sigctxt struct { ...@@ -11,9 +11,12 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontextt { func (c *sigctxt) regs() *mcontextt {
return (*mcontextt)(unsafe.Pointer(&(*ucontextt)(c.ctxt).uc_mcontext)) return (*mcontextt)(unsafe.Pointer(&(*ucontextt)(c.ctxt).uc_mcontext))
} }
func (c *sigctxt) rax() uint64 { return c.regs().__gregs[_REG_RAX] } func (c *sigctxt) rax() uint64 { return c.regs().__gregs[_REG_RAX] }
func (c *sigctxt) rbx() uint64 { return c.regs().__gregs[_REG_RBX] } func (c *sigctxt) rbx() uint64 { return c.regs().__gregs[_REG_RBX] }
func (c *sigctxt) rcx() uint64 { return c.regs().__gregs[_REG_RCX] } func (c *sigctxt) rcx() uint64 { return c.regs().__gregs[_REG_RCX] }
...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().__gregs[_REG_R12] } ...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().__gregs[_REG_R12] }
func (c *sigctxt) r13() uint64 { return c.regs().__gregs[_REG_R13] } func (c *sigctxt) r13() uint64 { return c.regs().__gregs[_REG_R13] }
func (c *sigctxt) r14() uint64 { return c.regs().__gregs[_REG_R14] } func (c *sigctxt) r14() uint64 { return c.regs().__gregs[_REG_R14] }
func (c *sigctxt) r15() uint64 { return c.regs().__gregs[_REG_R15] } func (c *sigctxt) r15() uint64 { return c.regs().__gregs[_REG_R15] }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) rip() uint64 { return c.regs().__gregs[_REG_RIP] } func (c *sigctxt) rip() uint64 { return c.regs().__gregs[_REG_RIP] }
func (c *sigctxt) rflags() uint64 { return c.regs().__gregs[_REG_RFLAGS] } func (c *sigctxt) rflags() uint64 { return c.regs().__gregs[_REG_RFLAGS] }
func (c *sigctxt) cs() uint64 { return c.regs().__gregs[_REG_CS] } func (c *sigctxt) cs() uint64 { return c.regs().__gregs[_REG_CS] }
func (c *sigctxt) fs() uint64 { return c.regs().__gregs[_REG_FS] } func (c *sigctxt) fs() uint64 { return c.regs().__gregs[_REG_FS] }
......
...@@ -11,7 +11,10 @@ type sigctxt struct { ...@@ -11,7 +11,10 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontextt { return &(*ucontextt)(c.ctxt).uc_mcontext } func (c *sigctxt) regs() *mcontextt { return &(*ucontextt)(c.ctxt).uc_mcontext }
func (c *sigctxt) r0() uint32 { return c.regs().__gregs[_REG_R0] } func (c *sigctxt) r0() uint32 { return c.regs().__gregs[_REG_R0] }
func (c *sigctxt) r1() uint32 { return c.regs().__gregs[_REG_R1] } func (c *sigctxt) r1() uint32 { return c.regs().__gregs[_REG_R1] }
func (c *sigctxt) r2() uint32 { return c.regs().__gregs[_REG_R2] } func (c *sigctxt) r2() uint32 { return c.regs().__gregs[_REG_R2] }
...@@ -27,7 +30,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().__gregs[_REG_R11] } ...@@ -27,7 +30,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().__gregs[_REG_R11] }
func (c *sigctxt) ip() uint32 { return c.regs().__gregs[_REG_R12] } func (c *sigctxt) ip() uint32 { return c.regs().__gregs[_REG_R12] }
func (c *sigctxt) sp() uint32 { return c.regs().__gregs[_REG_R13] } func (c *sigctxt) sp() uint32 { return c.regs().__gregs[_REG_R13] }
func (c *sigctxt) lr() uint32 { return c.regs().__gregs[_REG_R14] } func (c *sigctxt) lr() uint32 { return c.regs().__gregs[_REG_R14] }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint32 { return c.regs().__gregs[_REG_R15] } func (c *sigctxt) pc() uint32 { return c.regs().__gregs[_REG_R15] }
func (c *sigctxt) cpsr() uint32 { return c.regs().__gregs[_REG_CPSR] } func (c *sigctxt) cpsr() uint32 { return c.regs().__gregs[_REG_CPSR] }
func (c *sigctxt) fault() uint32 { return uint32(c.info._reason) } func (c *sigctxt) fault() uint32 { return uint32(c.info._reason) }
func (c *sigctxt) trap() uint32 { return 0 } func (c *sigctxt) trap() uint32 { return 0 }
......
...@@ -11,6 +11,8 @@ type sigctxt struct { ...@@ -11,6 +11,8 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext { func (c *sigctxt) regs() *sigcontext {
return (*sigcontext)(c.ctxt) return (*sigcontext)(c.ctxt)
} }
...@@ -23,7 +25,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().sc_edi } ...@@ -23,7 +25,11 @@ func (c *sigctxt) edi() uint32 { return c.regs().sc_edi }
func (c *sigctxt) esi() uint32 { return c.regs().sc_esi } func (c *sigctxt) esi() uint32 { return c.regs().sc_esi }
func (c *sigctxt) ebp() uint32 { return c.regs().sc_ebp } func (c *sigctxt) ebp() uint32 { return c.regs().sc_ebp }
func (c *sigctxt) esp() uint32 { return c.regs().sc_esp } func (c *sigctxt) esp() uint32 { return c.regs().sc_esp }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) eip() uint32 { return c.regs().sc_eip } func (c *sigctxt) eip() uint32 { return c.regs().sc_eip }
func (c *sigctxt) eflags() uint32 { return c.regs().sc_eflags } func (c *sigctxt) eflags() uint32 { return c.regs().sc_eflags }
func (c *sigctxt) cs() uint32 { return c.regs().sc_cs } func (c *sigctxt) cs() uint32 { return c.regs().sc_cs }
func (c *sigctxt) fs() uint32 { return c.regs().sc_fs } func (c *sigctxt) fs() uint32 { return c.regs().sc_fs }
......
...@@ -11,6 +11,8 @@ type sigctxt struct { ...@@ -11,6 +11,8 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext { func (c *sigctxt) regs() *sigcontext {
return (*sigcontext)(c.ctxt) return (*sigcontext)(c.ctxt)
} }
...@@ -31,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().sc_r12 } ...@@ -31,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return c.regs().sc_r12 }
func (c *sigctxt) r13() uint64 { return c.regs().sc_r13 } func (c *sigctxt) r13() uint64 { return c.regs().sc_r13 }
func (c *sigctxt) r14() uint64 { return c.regs().sc_r14 } func (c *sigctxt) r14() uint64 { return c.regs().sc_r14 }
func (c *sigctxt) r15() uint64 { return c.regs().sc_r15 } func (c *sigctxt) r15() uint64 { return c.regs().sc_r15 }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) rip() uint64 { return c.regs().sc_rip } func (c *sigctxt) rip() uint64 { return c.regs().sc_rip }
func (c *sigctxt) rflags() uint64 { return c.regs().sc_rflags } func (c *sigctxt) rflags() uint64 { return c.regs().sc_rflags }
func (c *sigctxt) cs() uint64 { return c.regs().sc_cs } func (c *sigctxt) cs() uint64 { return c.regs().sc_cs }
func (c *sigctxt) fs() uint64 { return c.regs().sc_fs } func (c *sigctxt) fs() uint64 { return c.regs().sc_fs }
......
...@@ -11,6 +11,8 @@ type sigctxt struct { ...@@ -11,6 +11,8 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext { func (c *sigctxt) regs() *sigcontext {
return (*sigcontext)(c.ctxt) return (*sigcontext)(c.ctxt)
} }
...@@ -30,7 +32,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().sc_r11 } ...@@ -30,7 +32,11 @@ func (c *sigctxt) fp() uint32 { return c.regs().sc_r11 }
func (c *sigctxt) ip() uint32 { return c.regs().sc_r12 } func (c *sigctxt) ip() uint32 { return c.regs().sc_r12 }
func (c *sigctxt) sp() uint32 { return c.regs().sc_usr_sp } func (c *sigctxt) sp() uint32 { return c.regs().sc_usr_sp }
func (c *sigctxt) lr() uint32 { return c.regs().sc_usr_lr } func (c *sigctxt) lr() uint32 { return c.regs().sc_usr_lr }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint32 { return c.regs().sc_pc } func (c *sigctxt) pc() uint32 { return c.regs().sc_pc }
func (c *sigctxt) cpsr() uint32 { return c.regs().sc_spsr } func (c *sigctxt) cpsr() uint32 { return c.regs().sc_spsr }
func (c *sigctxt) fault() uint32 { return c.sigaddr() } func (c *sigctxt) fault() uint32 { return c.sigaddr() }
func (c *sigctxt) trap() uint32 { return 0 } func (c *sigctxt) trap() uint32 { return 0 }
......
...@@ -53,7 +53,10 @@ func dumpregs(c *sigctxt) { ...@@ -53,7 +53,10 @@ func dumpregs(c *sigctxt) {
print("trap ", hex(c.trap()), "\n") print("trap ", hex(c.trap()), "\n")
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) } func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) }
func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) } func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) }
func (c *sigctxt) siglr() uintptr { return uintptr(c.link()) } func (c *sigctxt) siglr() uintptr { return uintptr(c.link()) }
......
...@@ -11,9 +11,12 @@ type sigctxt struct { ...@@ -11,9 +11,12 @@ type sigctxt struct {
ctxt unsafe.Pointer ctxt unsafe.Pointer
} }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontext { func (c *sigctxt) regs() *mcontext {
return (*mcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext)) return (*mcontext)(unsafe.Pointer(&(*ucontext)(c.ctxt).uc_mcontext))
} }
func (c *sigctxt) rax() uint64 { return uint64(c.regs().gregs[_REG_RAX]) } func (c *sigctxt) rax() uint64 { return uint64(c.regs().gregs[_REG_RAX]) }
func (c *sigctxt) rbx() uint64 { return uint64(c.regs().gregs[_REG_RBX]) } func (c *sigctxt) rbx() uint64 { return uint64(c.regs().gregs[_REG_RBX]) }
func (c *sigctxt) rcx() uint64 { return uint64(c.regs().gregs[_REG_RCX]) } func (c *sigctxt) rcx() uint64 { return uint64(c.regs().gregs[_REG_RCX]) }
...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return uint64(c.regs().gregs[_REG_R12]) } ...@@ -30,7 +33,11 @@ func (c *sigctxt) r12() uint64 { return uint64(c.regs().gregs[_REG_R12]) }
func (c *sigctxt) r13() uint64 { return uint64(c.regs().gregs[_REG_R13]) } func (c *sigctxt) r13() uint64 { return uint64(c.regs().gregs[_REG_R13]) }
func (c *sigctxt) r14() uint64 { return uint64(c.regs().gregs[_REG_R14]) } func (c *sigctxt) r14() uint64 { return uint64(c.regs().gregs[_REG_R14]) }
func (c *sigctxt) r15() uint64 { return uint64(c.regs().gregs[_REG_R15]) } func (c *sigctxt) r15() uint64 { return uint64(c.regs().gregs[_REG_R15]) }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) rip() uint64 { return uint64(c.regs().gregs[_REG_RIP]) } func (c *sigctxt) rip() uint64 { return uint64(c.regs().gregs[_REG_RIP]) }
func (c *sigctxt) rflags() uint64 { return uint64(c.regs().gregs[_REG_RFLAGS]) } func (c *sigctxt) rflags() uint64 { return uint64(c.regs().gregs[_REG_RFLAGS]) }
func (c *sigctxt) cs() uint64 { return uint64(c.regs().gregs[_REG_CS]) } func (c *sigctxt) cs() uint64 { return uint64(c.regs().gregs[_REG_CS]) }
func (c *sigctxt) fs() uint64 { return uint64(c.regs().gregs[_REG_FS]) } func (c *sigctxt) fs() uint64 { return uint64(c.regs().gregs[_REG_FS]) }
......
...@@ -202,15 +202,12 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { ...@@ -202,15 +202,12 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
} }
g := getg() g := getg()
if g == nil { if g == nil {
c := &sigctxt{info, ctx}
if sig == _SIGPROF { if sig == _SIGPROF {
// Ignore profiling signals that arrive on sigprofNonGoPC(c.sigpc())
// non-Go threads. On some systems they will
// be handled directly by the signal handler,
// by calling sigprofNonGo, in which case we won't
// get here anyhow.
return return
} }
badsignal(uintptr(sig), &sigctxt{info, ctx}) badsignal(uintptr(sig), c)
return return
} }
......
...@@ -80,11 +80,19 @@ import ( ...@@ -80,11 +80,19 @@ import (
func init() { func init() {
register("CgoPprofThread", CgoPprofThread) register("CgoPprofThread", CgoPprofThread)
register("CgoPprofThreadNoTraceback", CgoPprofThreadNoTraceback)
} }
func CgoPprofThread() { func CgoPprofThread() {
runtime.SetCgoTraceback(0, unsafe.Pointer(C.pprofCgoThreadTraceback), nil, nil) runtime.SetCgoTraceback(0, unsafe.Pointer(C.pprofCgoThreadTraceback), nil, nil)
pprofThread()
}
func CgoPprofThreadNoTraceback() {
pprofThread()
}
func pprofThread() {
f, err := ioutil.TempFile("", "prof") f, err := ioutil.TempFile("", "prof")
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
......
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