// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build (linux || freebsd || openbsd) && riscv64 package runtime import ( "internal/abi" "internal/goarch" "unsafe" ) func dumpregs(c *sigctxt) { print("ra ", hex(c.ra()), "\t") print("sp ", hex(c.sp()), "\n") print("gp ", hex(c.gp()), "\t") print("tp ", hex(c.tp()), "\n") print("t0 ", hex(c.t0()), "\t") print("t1 ", hex(c.t1()), "\n") print("t2 ", hex(c.t2()), "\t") print("s0 ", hex(c.s0()), "\n") print("s1 ", hex(c.s1()), "\t") print("a0 ", hex(c.a0()), "\n") print("a1 ", hex(c.a1()), "\t") print("a2 ", hex(c.a2()), "\n") print("a3 ", hex(c.a3()), "\t") print("a4 ", hex(c.a4()), "\n") print("a5 ", hex(c.a5()), "\t") print("a6 ", hex(c.a6()), "\n") print("a7 ", hex(c.a7()), "\t") print("s2 ", hex(c.s2()), "\n") print("s3 ", hex(c.s3()), "\t") print("s4 ", hex(c.s4()), "\n") print("s5 ", hex(c.s5()), "\t") print("s6 ", hex(c.s6()), "\n") print("s7 ", hex(c.s7()), "\t") print("s8 ", hex(c.s8()), "\n") print("s9 ", hex(c.s9()), "\t") print("s10 ", hex(c.s10()), "\n") print("s11 ", hex(c.s11()), "\t") print("t3 ", hex(c.t3()), "\n") print("t4 ", hex(c.t4()), "\t") print("t5 ", hex(c.t5()), "\n") print("t6 ", hex(c.t6()), "\t") print("pc ", hex(c.pc()), "\n") } //go:nosplit //go:nowritebarrierrec func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) } func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) } func (c *sigctxt) siglr() uintptr { return uintptr(c.ra()) } func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) } // preparePanic sets up the stack to look like a call to sigpanic. func (c *sigctxt) preparePanic(sig uint32, gp *g) { // We arrange RA, and pc to pretend the panicking // function calls sigpanic directly. // Always save RA to stack so that panics in leaf // functions are correctly handled. This smashes // the stack frame but we're not going back there // anyway. sp := c.sp() - goarch.PtrSize c.set_sp(sp) *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.ra() pc := gp.sigpc if shouldPushSigpanic(gp, pc, uintptr(c.ra())) { // Make it look the like faulting PC called sigpanic. c.set_ra(uint64(pc)) } // In case we are panicking from external C code c.set_gp(uint64(uintptr(unsafe.Pointer(gp)))) c.set_pc(uint64(abi.FuncPCABIInternal(sigpanic))) } func (c *sigctxt) pushCall(targetPC, resumePC uintptr) { // Push the LR to stack, as we'll clobber it in order to // push the call. The function being pushed is responsible // for restoring the LR and setting the SP back. // This extra slot is known to gentraceback. sp := c.sp() - goarch.PtrSize c.set_sp(sp) *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.ra() // Set up PC and LR to pretend the function being signaled // calls targetPC at resumePC. c.set_ra(uint64(resumePC)) c.set_pc(uint64(targetPC)) }