diff mbox series

libgo patch committed: Additional BSD-specific syscall wrappers

Message ID CAOyqgcWkzZeiZKHxw4HkQDqV0Ze_rB4NhdByFcNBVh1WGg3=aA@mail.gmail.com
State New
Headers show
Series libgo patch committed: Additional BSD-specific syscall wrappers | expand

Commit Message

Ian Lance Taylor Oct. 26, 2020, 10:04 p.m. UTC
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.

Ian
4768691a91c41e2fbc52248abea2f6ac5dcf8454

Comments

Rainer Orth Oct. 28, 2020, 9:53 a.m. UTC | #1
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
Ian Lance Taylor Oct. 28, 2020, 7:18 p.m. UTC | #2
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 mbox series

Patch

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