mirror of
https://github.com/golang/go
synced 2024-11-17 06:04:47 -07:00
runtime: implement signal for linux/loong64
Contributors to the loong64 port are: Weining Lu <luweining@loongson.cn> Lei Wang <wanglei@loongson.cn> Lingqin Gong <gonglingqin@loongson.cn> Xiaolin Zhao <zhaoxiaolin@loongson.cn> Meidan Li <limeidan@loongson.cn> Xiaojuan Zhai <zhaixiaojuan@loongson.cn> Qiyuan Pu <puqiyuan@loongson.cn> Guoqi Chen <chenguoqi@loongson.cn> This port has been updated to Go 1.15.6: https://github.com/loongson/go Updates #46229 Change-Id: Ifa0229d2044dd53683de4a2b3ab965b16263f267 Reviewed-on: https://go-review.googlesource.com/c/go/+/368075 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
c8de7628cb
commit
0084706528
212
src/runtime/defs_linux_loong64.go
Normal file
212
src/runtime/defs_linux_loong64.go
Normal file
@ -0,0 +1,212 @@
|
||||
// Generated using cgo, then manually converted into appropriate naming and code
|
||||
// for the Go runtime.
|
||||
// go tool cgo -godefs defs_linux.go defs1_linux.go defs2_linux.go
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
_ENOMEM = 0xc
|
||||
_ENOSYS = 0x26
|
||||
|
||||
_PROT_NONE = 0x0
|
||||
_PROT_READ = 0x1
|
||||
_PROT_WRITE = 0x2
|
||||
_PROT_EXEC = 0x4
|
||||
|
||||
_MAP_ANON = 0x20
|
||||
_MAP_PRIVATE = 0x2
|
||||
_MAP_FIXED = 0x10
|
||||
|
||||
_MADV_DONTNEED = 0x4
|
||||
_MADV_FREE = 0x8
|
||||
_MADV_HUGEPAGE = 0xe
|
||||
_MADV_NOHUGEPAGE = 0xf
|
||||
|
||||
_SA_RESTART = 0x10000000
|
||||
_SA_ONSTACK = 0x8000000
|
||||
_SA_SIGINFO = 0x4
|
||||
_SA_RESTORER = 0x0
|
||||
|
||||
_SI_KERNEL = 0x80
|
||||
_SI_TIMER = -0x2
|
||||
|
||||
_SIGHUP = 0x1
|
||||
_SIGINT = 0x2
|
||||
_SIGQUIT = 0x3
|
||||
_SIGILL = 0x4
|
||||
_SIGTRAP = 0x5
|
||||
_SIGABRT = 0x6
|
||||
_SIGBUS = 0x7
|
||||
_SIGFPE = 0x8
|
||||
_SIGKILL = 0x9
|
||||
_SIGUSR1 = 0xa
|
||||
_SIGSEGV = 0xb
|
||||
_SIGUSR2 = 0xc
|
||||
_SIGPIPE = 0xd
|
||||
_SIGALRM = 0xe
|
||||
_SIGSTKFLT = 0x10
|
||||
_SIGCHLD = 0x11
|
||||
_SIGCONT = 0x12
|
||||
_SIGSTOP = 0x13
|
||||
_SIGTSTP = 0x14
|
||||
_SIGTTIN = 0x15
|
||||
_SIGTTOU = 0x16
|
||||
_SIGURG = 0x17
|
||||
_SIGXCPU = 0x18
|
||||
_SIGXFSZ = 0x19
|
||||
_SIGVTALRM = 0x1a
|
||||
_SIGPROF = 0x1b
|
||||
_SIGWINCH = 0x1c
|
||||
_SIGIO = 0x1d
|
||||
_SIGPWR = 0x1e
|
||||
_SIGSYS = 0x1f
|
||||
|
||||
_SIGRTMIN = 0x20
|
||||
|
||||
_FPE_INTDIV = 0x1
|
||||
_FPE_INTOVF = 0x2
|
||||
_FPE_FLTDIV = 0x3
|
||||
_FPE_FLTOVF = 0x4
|
||||
_FPE_FLTUND = 0x5
|
||||
_FPE_FLTRES = 0x6
|
||||
_FPE_FLTINV = 0x7
|
||||
_FPE_FLTSUB = 0x8
|
||||
|
||||
_BUS_ADRALN = 0x1
|
||||
_BUS_ADRERR = 0x2
|
||||
_BUS_OBJERR = 0x3
|
||||
|
||||
_SEGV_MAPERR = 0x1
|
||||
_SEGV_ACCERR = 0x2
|
||||
|
||||
_ITIMER_REAL = 0x0
|
||||
_ITIMER_VIRTUAL = 0x1
|
||||
_ITIMER_PROF = 0x2
|
||||
|
||||
_CLOCK_THREAD_CPUTIME_ID = 0x3
|
||||
|
||||
_SIGEV_THREAD_ID = 0x4
|
||||
|
||||
_EPOLLIN = 0x1
|
||||
_EPOLLOUT = 0x4
|
||||
_EPOLLERR = 0x8
|
||||
_EPOLLHUP = 0x10
|
||||
_EPOLLRDHUP = 0x2000
|
||||
_EPOLLET = 0x80000000
|
||||
_EPOLL_CLOEXEC = 0x80000
|
||||
_EPOLL_CTL_ADD = 0x1
|
||||
_EPOLL_CTL_DEL = 0x2
|
||||
_EPOLL_CTL_MOD = 0x3
|
||||
)
|
||||
|
||||
type timespec struct {
|
||||
tv_sec int64
|
||||
tv_nsec int64
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func (ts *timespec) setNsec(ns int64) {
|
||||
ts.tv_sec = ns / 1e9
|
||||
ts.tv_nsec = ns % 1e9
|
||||
}
|
||||
|
||||
type timeval struct {
|
||||
tv_sec int64
|
||||
tv_usec int64
|
||||
}
|
||||
|
||||
func (tv *timeval) set_usec(x int32) {
|
||||
tv.tv_usec = int64(x)
|
||||
}
|
||||
|
||||
type itimerspec struct {
|
||||
it_interval timespec
|
||||
it_value timespec
|
||||
}
|
||||
|
||||
type itimerval struct {
|
||||
it_interval timeval
|
||||
it_value timeval
|
||||
}
|
||||
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
// below here is a union; sigev_notify_thread_id is the only field we use
|
||||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
pad_cgo_0 [4]byte
|
||||
data [8]byte // unaligned uintptr
|
||||
}
|
||||
|
||||
const (
|
||||
_O_RDONLY = 0x0
|
||||
_O_NONBLOCK = 0x800
|
||||
_O_CLOEXEC = 0x80000
|
||||
)
|
||||
|
||||
type sigactiont struct {
|
||||
sa_handler uintptr
|
||||
sa_flags uint64
|
||||
sa_mask uint64
|
||||
// Linux on loong64 does not have the sa_restorer field, but the setsig
|
||||
// function references it (for x86). Not much harm to include it at the end.
|
||||
sa_restorer uintptr
|
||||
}
|
||||
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_errno int32
|
||||
si_code int32
|
||||
__pad0 [1]int32
|
||||
// below here is a union; si_addr is the only field we use
|
||||
si_addr uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type usigset struct {
|
||||
val [16]uint64
|
||||
}
|
||||
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
ss_size uintptr
|
||||
}
|
||||
|
||||
type sigcontext struct {
|
||||
sc_pc uint64
|
||||
sc_regs [32]uint64
|
||||
sc_flags uint32
|
||||
sc_extcontext [0]uint64
|
||||
}
|
||||
|
||||
type ucontext struct {
|
||||
uc_flags uint64
|
||||
uc_link *ucontext
|
||||
uc_stack stackt
|
||||
uc_sigmask usigset
|
||||
uc_x_unused [0]uint8
|
||||
uc_pad_cgo_0 [8]byte
|
||||
uc_mcontext sigcontext
|
||||
}
|
75
src/runtime/signal_linux_loong64.go
Normal file
75
src/runtime/signal_linux_loong64.go
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright 2022 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 && loong64
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"internal/goarch"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type sigctxt struct {
|
||||
info *siginfo
|
||||
ctxt unsafe.Pointer
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
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) r1() uint64 { return c.regs().sc_regs[1] }
|
||||
func (c *sigctxt) r2() uint64 { return c.regs().sc_regs[2] }
|
||||
func (c *sigctxt) r3() uint64 { return c.regs().sc_regs[3] }
|
||||
func (c *sigctxt) r4() uint64 { return c.regs().sc_regs[4] }
|
||||
func (c *sigctxt) r5() uint64 { return c.regs().sc_regs[5] }
|
||||
func (c *sigctxt) r6() uint64 { return c.regs().sc_regs[6] }
|
||||
func (c *sigctxt) r7() uint64 { return c.regs().sc_regs[7] }
|
||||
func (c *sigctxt) r8() uint64 { return c.regs().sc_regs[8] }
|
||||
func (c *sigctxt) r9() uint64 { return c.regs().sc_regs[9] }
|
||||
func (c *sigctxt) r10() uint64 { return c.regs().sc_regs[10] }
|
||||
func (c *sigctxt) r11() uint64 { return c.regs().sc_regs[11] }
|
||||
func (c *sigctxt) r12() uint64 { return c.regs().sc_regs[12] }
|
||||
func (c *sigctxt) r13() uint64 { return c.regs().sc_regs[13] }
|
||||
func (c *sigctxt) r14() uint64 { return c.regs().sc_regs[14] }
|
||||
func (c *sigctxt) r15() uint64 { return c.regs().sc_regs[15] }
|
||||
func (c *sigctxt) r16() uint64 { return c.regs().sc_regs[16] }
|
||||
func (c *sigctxt) r17() uint64 { return c.regs().sc_regs[17] }
|
||||
func (c *sigctxt) r18() uint64 { return c.regs().sc_regs[18] }
|
||||
func (c *sigctxt) r19() uint64 { return c.regs().sc_regs[19] }
|
||||
func (c *sigctxt) r20() uint64 { return c.regs().sc_regs[20] }
|
||||
func (c *sigctxt) r21() uint64 { return c.regs().sc_regs[21] }
|
||||
func (c *sigctxt) r22() uint64 { return c.regs().sc_regs[22] }
|
||||
func (c *sigctxt) r23() uint64 { return c.regs().sc_regs[23] }
|
||||
func (c *sigctxt) r24() uint64 { return c.regs().sc_regs[24] }
|
||||
func (c *sigctxt) r25() uint64 { return c.regs().sc_regs[25] }
|
||||
func (c *sigctxt) r26() uint64 { return c.regs().sc_regs[26] }
|
||||
func (c *sigctxt) r27() uint64 { return c.regs().sc_regs[27] }
|
||||
func (c *sigctxt) r28() uint64 { return c.regs().sc_regs[28] }
|
||||
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) r31() uint64 { return c.regs().sc_regs[31] }
|
||||
func (c *sigctxt) sp() uint64 { return c.regs().sc_regs[3] }
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func (c *sigctxt) pc() uint64 { return c.regs().sc_pc }
|
||||
|
||||
func (c *sigctxt) link() uint64 { return c.regs().sc_regs[1] }
|
||||
|
||||
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_r31(x uint64) { c.regs().sc_regs[31] = x }
|
||||
func (c *sigctxt) set_r22(x uint64) { c.regs().sc_regs[22] = x }
|
||||
func (c *sigctxt) set_pc(x uint64) { c.regs().sc_pc = x }
|
||||
func (c *sigctxt) set_sp(x uint64) { c.regs().sc_regs[3] = x }
|
||||
func (c *sigctxt) set_link(x uint64) { c.regs().sc_regs[1] = x }
|
||||
|
||||
func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
|
||||
func (c *sigctxt) set_sigaddr(x uint64) {
|
||||
*(*uintptr)(add(unsafe.Pointer(c.info), 2*goarch.PtrSize)) = uintptr(x)
|
||||
}
|
98
src/runtime/signal_loong64.go
Normal file
98
src/runtime/signal_loong64.go
Normal file
@ -0,0 +1,98 @@
|
||||
// Copyright 2022 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 && loong64
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"internal/abi"
|
||||
"internal/goarch"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func dumpregs(c *sigctxt) {
|
||||
print("r0 ", hex(c.r0()), "\t")
|
||||
print("r1 ", hex(c.r1()), "\n")
|
||||
print("r2 ", hex(c.r2()), "\t")
|
||||
print("r3 ", hex(c.r3()), "\n")
|
||||
print("r4 ", hex(c.r4()), "\t")
|
||||
print("r5 ", hex(c.r5()), "\n")
|
||||
print("r6 ", hex(c.r6()), "\t")
|
||||
print("r7 ", hex(c.r7()), "\n")
|
||||
print("r8 ", hex(c.r8()), "\t")
|
||||
print("r9 ", hex(c.r9()), "\n")
|
||||
print("r10 ", hex(c.r10()), "\t")
|
||||
print("r11 ", hex(c.r11()), "\n")
|
||||
print("r12 ", hex(c.r12()), "\t")
|
||||
print("r13 ", hex(c.r13()), "\n")
|
||||
print("r14 ", hex(c.r14()), "\t")
|
||||
print("r15 ", hex(c.r15()), "\n")
|
||||
print("r16 ", hex(c.r16()), "\t")
|
||||
print("r17 ", hex(c.r17()), "\n")
|
||||
print("r18 ", hex(c.r18()), "\t")
|
||||
print("r19 ", hex(c.r19()), "\n")
|
||||
print("r20 ", hex(c.r20()), "\t")
|
||||
print("r21 ", hex(c.r21()), "\n")
|
||||
print("r22 ", hex(c.r22()), "\t")
|
||||
print("r23 ", hex(c.r23()), "\n")
|
||||
print("r24 ", hex(c.r24()), "\t")
|
||||
print("r25 ", hex(c.r25()), "\n")
|
||||
print("r26 ", hex(c.r26()), "\t")
|
||||
print("r27 ", hex(c.r27()), "\n")
|
||||
print("r28 ", hex(c.r28()), "\t")
|
||||
print("r29 ", hex(c.r29()), "\n")
|
||||
print("r30 ", hex(c.r30()), "\t")
|
||||
print("r31 ", hex(c.r31()), "\n")
|
||||
print("pc ", hex(c.pc()), "\t")
|
||||
print("link ", hex(c.link()), "\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.link()) }
|
||||
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 link, and pc to pretend the panicking
|
||||
// function calls sigpanic directly.
|
||||
// Always save LINK 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.link()
|
||||
|
||||
pc := gp.sigpc
|
||||
|
||||
if shouldPushSigpanic(gp, pc, uintptr(c.link())) {
|
||||
// Make it look the like faulting PC called sigpanic.
|
||||
c.set_link(uint64(pc))
|
||||
}
|
||||
|
||||
// In case we are panicking from external C code
|
||||
sigpanicPC := uint64(abi.FuncPCABIInternal(sigpanic))
|
||||
c.set_r31(sigpanicPC >> 32 << 32) // RSB register
|
||||
c.set_r22(uint64(uintptr(unsafe.Pointer(gp))))
|
||||
c.set_pc(sigpanicPC)
|
||||
}
|
||||
|
||||
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() - 8
|
||||
c.set_sp(sp)
|
||||
*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link()
|
||||
// Set up PC and LR to pretend the function being signaled
|
||||
// calls targetPC at resumePC.
|
||||
c.set_link(uint64(resumePC))
|
||||
c.set_pc(uint64(targetPC))
|
||||
}
|
Loading…
Reference in New Issue
Block a user