Message ID | CAOyqgcWkzZeiZKHxw4HkQDqV0Ze_rB4NhdByFcNBVh1WGg3=aA@mail.gmail.com |
---|---|
State | New |
Headers | show |
Series | libgo patch committed: Additional BSD-specific syscall wrappers | expand |
Hi Ian, > This libgo patch by Nikhil Benesch imports additional code from > upstream for handing system calls on BSD systems. This makes the > syscall package on NetBSD complete enough to compile the standard > library. Boostrapped and ran Go testsuite on x86_64-pc-linux-gnu. > Committed to mainline. this patch broke Solaris bootstrap: /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_solaris_largefile.go:12:1: error: redefinition of 'ReadDirent' 12 | func ReadDirent(fd int, buf []byte) (n int, err error) { | ^ /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:27:1: note: previous definition of 'ReadDirent' was here 27 | func ReadDirent(fd int, buf []byte) (n int, err error) { | ^ libcalls.go:2320:1: error: redefinition of 'raw_ptrace' 2320 | func raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) { | ^ libcalls.go:383:1: note: previous definition of 'raw_ptrace' was here 383 | func raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) { | ^ /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:33:16: error: reference to undefined name 'Getdirentries' 33 | return Getdirentries(fd, buf, base) | ^ /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:33:9: error: not enough arguments to return 33 | return Getdirentries(fd, buf, base) | ^ /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:69:21: error: reference to undefined name 'nametomib' 69 | mib, err := nametomib(name) | ^ /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:98:21: error: reference to undefined name 'nametomib' 98 | mib, err := nametomib(name) | ^ libcalls.go:2321:85: error: argument 4 has incompatible type 2321 | _r := c_ptrace(_C_int(request), Pid_t(pid), (*byte)(unsafe.Pointer(addr)), (*byte)(unsafe.Pointer(data))) | ^ make[4]: *** [Makefile:2912: syscall.lo] Error 1 Of the functions used there, ptrace (32-bit only) is already handled and sysctl, paccept and flock don't exist on Solaris. Only pipe2 does exist, but it's only in Solaris 11.4 and Illumos, not Solaris 11.3, so better left off for now. Fixed by removing the solaris build tag. Rainer
On Wed, Oct 28, 2020 at 2:53 AM Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote: > > > This libgo patch by Nikhil Benesch imports additional code from > > upstream for handing system calls on BSD systems. This makes the > > syscall package on NetBSD complete enough to compile the standard > > library. Boostrapped and ran Go testsuite on x86_64-pc-linux-gnu. > > Committed to mainline. > > this patch broke Solaris bootstrap: > > /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_solaris_largefile.go:12:1: error: redefinition of 'ReadDirent' > 12 | func ReadDirent(fd int, buf []byte) (n int, err error) { > | ^ > /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:27:1: note: previous definition of 'ReadDirent' was here > 27 | func ReadDirent(fd int, buf []byte) (n int, err error) { > | ^ > libcalls.go:2320:1: error: redefinition of 'raw_ptrace' > 2320 | func raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) { > | ^ > libcalls.go:383:1: note: previous definition of 'raw_ptrace' was here > 383 | func raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) { > | ^ > /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:33:16: error: reference to undefined name 'Getdirentries' > 33 | return Getdirentries(fd, buf, base) > | ^ > /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:33:9: error: not enough arguments to return > 33 | return Getdirentries(fd, buf, base) > | ^ > /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:69:21: error: reference to undefined name 'nametomib' > 69 | mib, err := nametomib(name) > | ^ > /vol/gcc/src/hg/master/local/libgo/go/syscall/libcall_bsd.go:98:21: error: reference to undefined name 'nametomib' > 98 | mib, err := nametomib(name) > | ^ > libcalls.go:2321:85: error: argument 4 has incompatible type > 2321 | _r := c_ptrace(_C_int(request), Pid_t(pid), (*byte)(unsafe.Pointer(addr)), (*byte)(unsafe.Pointer(data))) > | ^ > make[4]: *** [Makefile:2912: syscall.lo] Error 1 > > Of the functions used there, ptrace (32-bit only) is already handled and > sysctl, paccept and flock don't exist on Solaris. Only pipe2 does > exist, but it's only in Solaris 11.4 and Illumos, not Solaris 11.3, so > better left off for now. > > Fixed by removing the solaris build tag. Thanks, yes, using the solaris build tag there was a clear mistake. Committed this patch. Ian 757c0310a69055e89e6abdf40acfd3de07ab927f diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 1f65809fc81..45aafaab5c5 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -be0d2cc2df9f98d967c242594838f86362dae2e7 +88a25df9133e9a1fc28a00b08ee30d7e5ab2cdbb The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/go/syscall/libcall_bsd.go b/libgo/go/syscall/libcall_bsd.go index f13d3bcbe16..1dd957c4531 100644 --- a/libgo/go/syscall/libcall_bsd.go +++ b/libgo/go/syscall/libcall_bsd.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd netbsd openbsd solaris +// +build darwin dragonfly freebsd netbsd openbsd // BSD library calls.
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 3ad6c9633f1..c3a45c8a959 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -28f3df468666787f83f94220312383a7c267a8ce +66657f88f820f2b0cab3c1c0a7d8b7f8923af7fb The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/go/syscall/libcall_bsd.go b/libgo/go/syscall/libcall_bsd.go new file mode 100644 index 00000000000..f13d3bcbe16 --- /dev/null +++ b/libgo/go/syscall/libcall_bsd.go @@ -0,0 +1,113 @@ +// Copyright 2020 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. + +// +build darwin dragonfly freebsd netbsd openbsd solaris + +// BSD library calls. + +package syscall + +import ( + "unsafe" +) + +//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) +//sysctl(mib *_C_int, miblen uintptr, old *byte, oldlen *uintptr, new *byte, newlen uintptr) _C_int + +//sysnb raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) +//ptrace(request _C_int, pid Pid_t, addr *byte, data _C_int) _C_int + +//sys paccept(fd int, rsa *RawSockaddrAny, addrlen *Socklen_t, sigmask *_sigset_t, flags int) (nfd int, err error) +//paccept(s _C_int, rsa *RawSockaddrAny, addrlen *Socklen_t, sigmask *_sigset_t, flags int) _C_int + +//sys Flock(fd int, how int) (err error) +//flock(fd _C_int, how _C_int) _C_int + +func ReadDirent(fd int, buf []byte) (n int, err error) { + // Final argument is (basep *uintptr) and the syscall doesn't take nil. + // 64 bits should be enough. (32 bits isn't even on 386). Since the + // actual system call is getdirentries64, 64 is a good guess. + // TODO(rsc): Can we use a single global basep for all calls? + var base = (*uintptr)(unsafe.Pointer(new(uint64))) + return Getdirentries(fd, buf, base) +} + +func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { + var rsa RawSockaddrAny + var len Socklen_t = SizeofSockaddrAny + nfd, err = paccept(fd, &rsa, &len, nil, flags) + if err != nil { + return + } + if len > SizeofSockaddrAny { + panic("RawSockaddrAny too small") + } + sa, err = anyToSockaddr(&rsa) + if err != nil { + Close(nfd) + nfd = 0 + } + return +} + +//sysnb pipe2(p *[2]_C_int, flags int) (err error) +//pipe2(p *[2]_C_int, flags _C_int) _C_int +func Pipe2(p []int, flags int) (err error) { + if len(p) != 2 { + return EINVAL + } + var pp [2]_C_int + err = pipe2(&pp, flags) + p[0] = int(pp[0]) + p[1] = int(pp[1]) + return +} + +func Sysctl(name string) (value string, err error) { + // Translate name to mib number. + mib, err := nametomib(name) + if err != nil { + return "", err + } + + // Find size. + n := uintptr(0) + if err = sysctl(mib, nil, &n, nil, 0); err != nil { + return "", err + } + if n == 0 { + return "", nil + } + + // Read into buffer of that size. + buf := make([]byte, n) + if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil { + return "", err + } + + // Throw away terminating NUL. + if n > 0 && buf[n-1] == '\x00' { + n-- + } + return string(buf[0:n]), nil +} + +func SysctlUint32(name string) (value uint32, err error) { + // Translate name to mib number. + mib, err := nametomib(name) + if err != nil { + return 0, err + } + + // Read into buffer of that size. + n := uintptr(4) + buf := make([]byte, 4) + if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil { + return 0, err + } + if n != 4 { + return 0, EIO + } + return *(*uint32)(unsafe.Pointer(&buf[0])), nil +} diff --git a/libgo/go/syscall/syscall_netbsd.go b/libgo/go/syscall/syscall_netbsd.go index bbc6799e3e6..c3a79e3275c 100644 --- a/libgo/go/syscall/syscall_netbsd.go +++ b/libgo/go/syscall/syscall_netbsd.go @@ -18,6 +18,34 @@ func direntNamlen(buf []byte) (uint64, bool) { return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) } +//sys Getdents(fd int, buf []byte) (n int, err error) +//getdents(fd _C_int, buf *byte, nbytes uintptr) _C_int + +func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { + n, err = Getdents(fd, buf) + if err != nil || basep == nil { + return + } + + var off int64 + off, err = Seek(fd, 0, 1 /* SEEK_CUR */) + if err != nil { + *basep = ^uintptr(0) + return + } + *basep = uintptr(off) + if unsafe.Sizeof(*basep) == 8 { + return + } + if off>>32 != 0 { + // We can't stuff the offset back into a uintptr, so any + // future calls would be suspect. Generate an error. + // EIO is allowed by getdirentries. + err = EIO + } + return +} + func sysctlNodes(mib []_C_int) (nodes []Sysctlnode, err error) { var olen uintptr