gccgo: fix runtime compilation on NetBSD

si_code in siginfo_t is a macro on NetBSD, not a member of the
struct itself, so add a C trampoline for receiving its value.

Also replace references to mos.waitsemacount with the replacement and
add some helpers from os_netbsd.go in the GC repository.

Update golang/go#38538.

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/228918
This commit is contained in:
Benny Siegert 2020-04-20 16:11:14 +02:00 committed by Ian Lance Taylor
parent 8ab392f97b
commit 8e841bd419
5 changed files with 54 additions and 7 deletions

View File

@ -1,4 +1,4 @@
0fe7a277c5d22265a73a4d216bd5d81799634453 b76c83f34c006938fe6c3311d949496990bc5db9
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.

View File

@ -68,9 +68,9 @@ func semasleep(ns int64) int32 {
} }
for { for {
v := atomic.Load(&_g_.m.mos.waitsemacount) v := atomic.Load(&_g_.m.waitsemacount)
if v > 0 { if v > 0 {
if atomic.Cas(&_g_.m.mos.waitsemacount, v, v-1) { if atomic.Cas(&_g_.m.waitsemacount, v, v-1) {
return 0 // semaphore acquired return 0 // semaphore acquired
} }
continue continue
@ -96,15 +96,15 @@ func semasleep(ns int64) int32 {
//go:nosplit //go:nosplit
func semawakeup(mp *m) { func semawakeup(mp *m) {
atomic.Xadd(&mp.mos.waitsemacount, 1) atomic.Xadd(&mp.waitsemacount, 1)
// From NetBSD's _lwp_unpark(2) manual: // From NetBSD's _lwp_unpark(2) manual:
// "If the target LWP is not currently waiting, it will return // "If the target LWP is not currently waiting, it will return
// immediately upon the next call to _lwp_park()." // immediately upon the next call to _lwp_park()."
ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.mos.waitsemacount)) ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.waitsemacount))
if ret != 0 && ret != _ESRCH { if ret != 0 && ret != _ESRCH {
// semawakeup can be called on signal stack. // semawakeup can be called on signal stack.
systemstack(func() { systemstack(func() {
print("thrwakeup addr=", &mp.mos.waitsemacount, " sem=", mp.mos.waitsemacount, " ret=", ret, "\n") print("thrwakeup addr=", &mp.waitsemacount, " sem=", mp.waitsemacount, " ret=", ret, "\n")
}) })
} }
} }
@ -115,3 +115,34 @@ func osinit() {
physPageSize = getPageSize() physPageSize = getPageSize()
} }
} }
func sysargs(argc int32, argv **byte) {
n := argc + 1
// skip over argv, envp to get to auxv
for argv_index(argv, n) != nil {
n++
}
// skip NULL separator
n++
// now argv+n is auxv
auxv := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*sys.PtrSize))
sysauxv(auxv[:])
}
const (
_AT_NULL = 0 // Terminates the vector
_AT_PAGESZ = 6 // Page size in bytes
)
func sysauxv(auxv []uintptr) {
for i := 0; auxv[i] != _AT_NULL; i += 2 {
tag, val := auxv[i], auxv[i+1]
switch tag {
case _AT_PAGESZ:
physPageSize = val
}
}
}

View File

@ -60,7 +60,7 @@ type sigctxt struct {
} }
func (c *sigctxt) sigcode() uint64 { func (c *sigctxt) sigcode() uint64 {
return uint64(c.info.si_code) return uint64(getSiginfoCode(c.info))
} }
//go:nosplit //go:nosplit

View File

@ -297,6 +297,10 @@ func getSigactionHandler(*_sigaction) uintptr
//go:noescape //go:noescape
func setSigactionHandler(*_sigaction, uintptr) func setSigactionHandler(*_sigaction, uintptr)
// Get signal code, written in C.
//go:noescape
func getSiginfoCode(*_siginfo_t) uintptr
// Retrieve fields from the siginfo_t and ucontext_t pointers passed // Retrieve fields from the siginfo_t and ucontext_t pointers passed
// to a signal handler using C, as they are often hidden in a union. // to a signal handler using C, as they are often hidden in a union.
// Returns and, if available, PC where signal occurred. // Returns and, if available, PC where signal occurred.

View File

@ -179,6 +179,18 @@ setSigactionHandler(struct sigaction* sa, uintptr handler)
// C code to fetch values from the siginfo_t and ucontext_t pointers // C code to fetch values from the siginfo_t and ucontext_t pointers
// passed to a signal handler. // passed to a signal handler.
uintptr getSiginfoCode(siginfo_t *)
__attribute__ ((no_split_stack));
uintptr getSiginfoCode(siginfo_t *)
__asm__ (GOSYM_PREFIX "runtime.getSiginfoCode");
uintptr
getSiginfoCode(siginfo_t *info)
{
return (uintptr)(info->si_code);
}
struct getSiginfoRet { struct getSiginfoRet {
uintptr sigaddr; uintptr sigaddr;
uintptr sigpc; uintptr sigpc;