From 68402af1c68301c6bc852ddba6c63966ed706178 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 21 Sep 2020 12:45:43 -0700 Subject: libgo: don't put golang.org packages in zstdpkglist.go This ensures that internal/goroot.IsStandardPackage does not treat golang.org packages as being in the standard library. For golang/go#41368 Fixes golang/go#41499 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/256319 --- libgo/Makefile.am | 2 +- libgo/Makefile.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'libgo') diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 9ce0cab..e3f08a2 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -620,7 +620,7 @@ s-zstdpkglist: Makefile echo 'package goroot' > zstdpkglist.go.tmp echo "" >> zstdpkglist.go.tmp echo 'var stdpkg = map[string]bool{' >> zstdpkglist.go.tmp - echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_./]*_c\.lo||g' | sed 's|\([a-z0-9_./]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp + echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_./]*_c\.lo||g' | sed 's|golang\.org/[a-z0-9_./]*\.lo||g' | sed 's|\([a-z0-9_./]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp echo '}' >> zstdpkglist.go.tmp $(SHELL) $(srcdir)/mvifdiff.sh zstdpkglist.go.tmp zstdpkglist.go $(STAMP) $@ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index b577083..18b1a06 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -2784,7 +2784,7 @@ s-zstdpkglist: Makefile echo 'package goroot' > zstdpkglist.go.tmp echo "" >> zstdpkglist.go.tmp echo 'var stdpkg = map[string]bool{' >> zstdpkglist.go.tmp - echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_./]*_c\.lo||g' | sed 's|\([a-z0-9_./]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp + echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_./]*_c\.lo||g' | sed 's|golang\.org/[a-z0-9_./]*\.lo||g' | sed 's|\([a-z0-9_./]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp echo '}' >> zstdpkglist.go.tmp $(SHELL) $(srcdir)/mvifdiff.sh zstdpkglist.go.tmp zstdpkglist.go $(STAMP) $@ -- cgit v1.1 From be3027e9c8366d92f68e6b3021c1cbe815648480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Wed, 16 Sep 2020 13:58:17 +0200 Subject: go/internal/gccgoimporter: recognize aixbigafMagic archives Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/255201 --- libgo/go/go/internal/gccgoimporter/importer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/go/go/internal/gccgoimporter/importer.go b/libgo/go/go/internal/gccgoimporter/importer.go index ff484a7..391477d 100644 --- a/libgo/go/go/internal/gccgoimporter/importer.go +++ b/libgo/go/go/internal/gccgoimporter/importer.go @@ -198,7 +198,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo return } - if magics == archiveMagic { + if magics == archiveMagic || magics == aixbigafMagic { reader, err = arExportData(reader) if err != nil { return -- cgit v1.1 From 63cd53d2f5da07856340bbea11ee09ab1125e8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Tue, 26 May 2020 11:31:37 +0200 Subject: runtime, net: fix build errors on AIX Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/235158 --- libgo/go/internal/cpu/cpu_no_init.go | 1 + libgo/go/internal/cpu/cpu_ppc64x.go | 44 ------------------------------------ libgo/go/internal/cpu/cpu_ppcx.go | 44 ++++++++++++++++++++++++++++++++++++ libgo/go/net/interface_aix.go | 2 -- libgo/go/runtime/os_aix.go | 11 ++++----- libgo/mksysinfo.sh | 9 +++++++- libgo/sysinfo.c | 8 +++++++ 7 files changed, 66 insertions(+), 53 deletions(-) delete mode 100644 libgo/go/internal/cpu/cpu_ppc64x.go create mode 100644 libgo/go/internal/cpu/cpu_ppcx.go (limited to 'libgo') diff --git a/libgo/go/internal/cpu/cpu_no_init.go b/libgo/go/internal/cpu/cpu_no_init.go index fb381e1..e7ff873 100644 --- a/libgo/go/internal/cpu/cpu_no_init.go +++ b/libgo/go/internal/cpu/cpu_no_init.go @@ -6,6 +6,7 @@ // +build !amd64 // +build !arm // +build !arm64 +// +build !ppc // +build !ppc64 // +build !ppc64le // +build !s390x diff --git a/libgo/go/internal/cpu/cpu_ppc64x.go b/libgo/go/internal/cpu/cpu_ppc64x.go deleted file mode 100644 index b726cc8..0000000 --- a/libgo/go/internal/cpu/cpu_ppc64x.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2017 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 ppc64 ppc64le - -package cpu - -// ppc64x doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. -// These are initialized by archauxv and should not be changed after they are -// initialized. -// On aix/ppc64, these values are initialized early in the runtime in runtime/os_aix.go. -var HWCap uint -var HWCap2 uint - -// HWCAP/HWCAP2 bits. These are exposed by the kernel. -const ( - // ISA Level - PPC_FEATURE2_ARCH_2_07 = 0x80000000 - PPC_FEATURE2_ARCH_3_00 = 0x00800000 - - // CPU features - PPC_FEATURE2_DARN = 0x00200000 - PPC_FEATURE2_SCV = 0x00100000 -) - -func doinit() { - options = []option{ - {Name: "darn", Feature: &PPC64.HasDARN}, - {Name: "scv", Feature: &PPC64.HasSCV}, - {Name: "power9", Feature: &PPC64.IsPOWER9}, - {Name: "power8", Feature: &PPC64.IsPOWER8}, - } - - // HWCAP2 feature bits - PPC64.IsPOWER8 = isSet(HWCap2, PPC_FEATURE2_ARCH_2_07) - PPC64.IsPOWER9 = isSet(HWCap2, PPC_FEATURE2_ARCH_3_00) - PPC64.HasDARN = isSet(HWCap2, PPC_FEATURE2_DARN) - PPC64.HasSCV = isSet(HWCap2, PPC_FEATURE2_SCV) -} - -func isSet(hwc uint, value uint) bool { - return hwc&value != 0 -} diff --git a/libgo/go/internal/cpu/cpu_ppcx.go b/libgo/go/internal/cpu/cpu_ppcx.go new file mode 100644 index 0000000..56ff875 --- /dev/null +++ b/libgo/go/internal/cpu/cpu_ppcx.go @@ -0,0 +1,44 @@ +// Copyright 2017 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 ppc ppc64 ppc64le + +package cpu + +// ppc64x doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. +// These are initialized by archauxv and should not be changed after they are +// initialized. +// On aix/ppc64, these values are initialized early in the runtime in runtime/os_aix.go. +var HWCap uint +var HWCap2 uint + +// HWCAP/HWCAP2 bits. These are exposed by the kernel. +const ( + // ISA Level + PPC_FEATURE2_ARCH_2_07 = 0x80000000 + PPC_FEATURE2_ARCH_3_00 = 0x00800000 + + // CPU features + PPC_FEATURE2_DARN = 0x00200000 + PPC_FEATURE2_SCV = 0x00100000 +) + +func doinit() { + options = []option{ + {Name: "darn", Feature: &PPC64.HasDARN}, + {Name: "scv", Feature: &PPC64.HasSCV}, + {Name: "power9", Feature: &PPC64.IsPOWER9}, + {Name: "power8", Feature: &PPC64.IsPOWER8}, + } + + // HWCAP2 feature bits + PPC64.IsPOWER8 = isSet(HWCap2, PPC_FEATURE2_ARCH_2_07) + PPC64.IsPOWER9 = isSet(HWCap2, PPC_FEATURE2_ARCH_3_00) + PPC64.HasDARN = isSet(HWCap2, PPC_FEATURE2_DARN) + PPC64.HasSCV = isSet(HWCap2, PPC_FEATURE2_SCV) +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/libgo/go/net/interface_aix.go b/libgo/go/net/interface_aix.go index f57c5ff..bd55386 100644 --- a/libgo/go/net/interface_aix.go +++ b/libgo/go/net/interface_aix.go @@ -33,8 +33,6 @@ const _RTAX_NETMASK = 2 const _RTAX_IFA = 5 const _RTAX_MAX = 8 -const _SIOCGIFMTU = -0x3fd796aa - func getIfList() ([]byte, error) { needed, err := syscall.Getkerninfo(_KINFO_RT_IFLIST, 0, 0, 0) if err != nil { diff --git a/libgo/go/runtime/os_aix.go b/libgo/go/runtime/os_aix.go index b337330..951aeb6 100644 --- a/libgo/go/runtime/os_aix.go +++ b/libgo/go/runtime/os_aix.go @@ -46,7 +46,7 @@ func clock_gettime(clock_id int64, timeout *timespec) int32 //go:nosplit func semacreate(mp *m) { - if mp.mos.waitsema != 0 { + if mp.waitsema != 0 { return } @@ -59,7 +59,7 @@ func semacreate(mp *m) { if sem_init(sem, 0, 0) != 0 { throw("sem_init") } - mp.mos.waitsema = uintptr(unsafe.Pointer(sem)) + mp.waitsema = uintptr(unsafe.Pointer(sem)) } //go:nosplit @@ -85,7 +85,7 @@ func semasleep(ns int64) int32 { ts.tv_sec = timespec_sec_t(sec) ts.tv_nsec = timespec_nsec_t(nsec) - if sem_timedwait((*semt)(unsafe.Pointer(_m_.mos.waitsema)), &ts) != 0 { + if sem_timedwait((*semt)(unsafe.Pointer(_m_.waitsema)), &ts) != 0 { err := errno() if err == _ETIMEDOUT || err == _EAGAIN || err == _EINTR { return -1 @@ -96,7 +96,7 @@ func semasleep(ns int64) int32 { return 0 } for { - r1 := sem_wait((*semt)(unsafe.Pointer(_m_.mos.waitsema))) + r1 := sem_wait((*semt)(unsafe.Pointer(_m_.waitsema))) if r1 == 0 { break } @@ -110,7 +110,7 @@ func semasleep(ns int64) int32 { //go:nosplit func semawakeup(mp *m) { - if sem_post((*semt)(unsafe.Pointer(mp.mos.waitsema))) != 0 { + if sem_post((*semt)(unsafe.Pointer(mp.waitsema))) != 0 { throw("sem_post") } } @@ -128,7 +128,6 @@ const ( const ( // getsystemcfg constants - _SC_IMPL = 2 _IMPL_POWER8 = 0x10000 _IMPL_POWER9 = 0x20000 ) diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh index bd2ba32..9671e39 100755 --- a/libgo/mksysinfo.sh +++ b/libgo/mksysinfo.sh @@ -1041,9 +1041,16 @@ grep '^const _IFF' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(IFF[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} grep '^const _IFNAMSIZ' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(IFNAMSIZ[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} -grep '^const _SIOC' gen-sysinfo.go | +grep '^const _SIOC' gen-sysinfo.go | \ + grep -v '_val =' | \ sed -e 's/^\(const \)_\(SIOC[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} +if ! grep '^const SIOCGIFMTU' ${OUT} >/dev/null 2>&1; then + if grep '^const _SIOCGIFMTU_val' ${OUT} >/dev/null 2>&1; then + echo 'const SIOCGIFMTU = _SIOCGIFMTU_val' >> ${OUT} + fi +fi + # The ifaddrmsg struct. grep '^type _ifaddrmsg ' gen-sysinfo.go | \ sed -e 's/_ifaddrmsg/IfAddrmsg/' \ diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c index 7640559..6ea990f 100644 --- a/libgo/sysinfo.c +++ b/libgo/sysinfo.c @@ -281,6 +281,14 @@ enum { #endif }; +// SIOCGIFMTU can't be added in the above enum as it might +// be signed in some OSes. +#ifdef SIOCGIFMTU +enum { + SIOCGIFMTU_val = SIOCGIFMTU, +}; +#endif + #if defined(HAVE_SYS_EPOLL_H) enum { epoll_data_offset = offsetof(struct epoll_event, data) -- cgit v1.1 From 1260f69aeb96f98ebefdbb852a4e868b8926eb0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Tue, 7 May 2019 13:57:40 +0200 Subject: syscall: remove ptrace syscall on ppc64 ptrace is available only for 32 bits programs. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/252558 --- libgo/go/syscall/libcall_aix.go | 3 --- libgo/go/syscall/syscall_aix_ppc.go | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'libgo') diff --git a/libgo/go/syscall/libcall_aix.go b/libgo/go/syscall/libcall_aix.go index 8d9f59e..27b469e 100644 --- a/libgo/go/syscall/libcall_aix.go +++ b/libgo/go/syscall/libcall_aix.go @@ -16,9 +16,6 @@ const SYS_EXECVE = 0 //sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) //open64at(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int -//sys ptrace(request int, id int, addr uintptr, data int, buff uintptr) (val int) -//ptrace(request _C_int, id int, addr uintptr, data _C_int, buff *byte) _C_int - //sys ptrace64(request int, id int64, addr int64, data int, buff uintptr) (err error) //ptrace64(request _C_int, id int64, addr int64, data _C_int, buff *byte) _C_int diff --git a/libgo/go/syscall/syscall_aix_ppc.go b/libgo/go/syscall/syscall_aix_ppc.go index 83ed1e6..23333e8 100644 --- a/libgo/go/syscall/syscall_aix_ppc.go +++ b/libgo/go/syscall/syscall_aix_ppc.go @@ -8,6 +8,9 @@ package syscall import "unsafe" +//sys ptrace(request int, id int, addr uintptr, data int, buff uintptr) (val int) +//ptrace(request _C_int, id int, addr uintptr, data _C_int, buff *byte) _C_int + // AIX does not define a specific structure but instead uses separate // ptrace calls for the different registers. type PtraceRegs struct { -- cgit v1.1 From e884ced05231a04b1a3c70ece7237d0b1eeebf19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Fri, 3 May 2019 16:53:13 +0200 Subject: syscall: fix TestForeground for AIX Syscall function can't be used on AIX. Therefore, Ioctl in TestForeground must call raw_ioctl. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/175080 --- libgo/go/syscall/export_aix_test.go | 16 ++++++++++++++++ libgo/go/syscall/export_unix_test.go | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 libgo/go/syscall/export_aix_test.go (limited to 'libgo') diff --git a/libgo/go/syscall/export_aix_test.go b/libgo/go/syscall/export_aix_test.go new file mode 100644 index 0000000..044337b --- /dev/null +++ b/libgo/go/syscall/export_aix_test.go @@ -0,0 +1,16 @@ +// Copyright 2019 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 aix + +package syscall + +import ( + "unsafe" +) + +func Ioctl(fd, req, arg uintptr) (err Errno) { + _, err = raw_ioctl_ptr(int(fd), req, unsafe.Pointer(arg)) + return err +} diff --git a/libgo/go/syscall/export_unix_test.go b/libgo/go/syscall/export_unix_test.go index dc11f45..4d67be9 100644 --- a/libgo/go/syscall/export_unix_test.go +++ b/libgo/go/syscall/export_unix_test.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 aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris +// +build darwin dragonfly freebsd hurd linux netbsd openbsd solaris package syscall -- cgit v1.1 From 10a83805e047a583348e8bef18b966ecb8eee5d4 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 22 Sep 2020 20:30:08 -0700 Subject: libgo: update to Go1.15.2 release Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/256618 --- libgo/MERGE | 2 +- libgo/VERSION | 2 +- libgo/go/cmd/go/internal/test/test.go | 8 +- libgo/go/cmd/go/internal/test/testflag.go | 29 ++++- libgo/go/cmd/go/testdata/script/test_flags.txt | 132 +++++++++++++++++++++ libgo/go/cmd/internal/test2json/test2json.go | 65 ++++++---- .../internal/test2json/testdata/benchshort.json | 1 - .../go/cmd/internal/test2json/testdata/empty.json | 0 .../go/cmd/internal/test2json/testdata/empty.test | 0 .../internal/test2json/testdata/issue29755.json | 38 ++++++ .../internal/test2json/testdata/issue29755.test | 27 +++++ .../go/cmd/internal/test2json/testdata/panic.json | 19 +++ .../go/cmd/internal/test2json/testdata/panic.test | 17 +++ .../go/cmd/internal/test2json/testdata/smiley.json | 22 ++-- .../go/cmd/internal/test2json/testdata/smiley.test | 22 ++-- libgo/go/cmd/internal/test2json/testdata/vet.json | 22 ++-- libgo/go/cmd/internal/test2json/testdata/vet.test | 22 ++-- libgo/go/cmd/test2json/main.go | 6 +- libgo/go/internal/poll/copy_file_range_linux.go | 10 +- libgo/go/net/http/cgi/child.go | 36 ++++-- libgo/go/net/http/cgi/child_test.go | 69 +++++++++++ libgo/go/net/http/cgi/integration_test.go | 53 ++++++++- libgo/go/net/http/fcgi/child.go | 39 ++++-- libgo/go/net/http/fcgi/fcgi_test.go | 53 +++++++++ libgo/go/net/mail/message.go | 13 +- libgo/go/net/mail/message_test.go | 32 +++++ libgo/go/runtime/checkptr_test.go | 1 + libgo/go/runtime/lockrank_off.go | 10 ++ libgo/go/runtime/testdata/testprog/checkptr.go | 8 ++ libgo/go/sync/map.go | 1 + libgo/go/sync/map_test.go | 24 ++++ libgo/go/testing/testing.go | 29 ++++- libgo/merge.sh | 4 +- 33 files changed, 708 insertions(+), 108 deletions(-) create mode 100644 libgo/go/cmd/go/testdata/script/test_flags.txt create mode 100644 libgo/go/cmd/internal/test2json/testdata/empty.json create mode 100644 libgo/go/cmd/internal/test2json/testdata/empty.test create mode 100644 libgo/go/cmd/internal/test2json/testdata/issue29755.json create mode 100644 libgo/go/cmd/internal/test2json/testdata/issue29755.test create mode 100644 libgo/go/cmd/internal/test2json/testdata/panic.json create mode 100644 libgo/go/cmd/internal/test2json/testdata/panic.test (limited to 'libgo') diff --git a/libgo/MERGE b/libgo/MERGE index a84f1e3..cfbf488 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -c4f8cb43caf0bcd0c730d7d04a3fce129393cecc +9706f510a5e2754595d716bd64be8375997311fb The first line of this file holds the git revision number of the last merge done from the master library sources. diff --git a/libgo/VERSION b/libgo/VERSION index 2d962d8..c19def3 100644 --- a/libgo/VERSION +++ b/libgo/VERSION @@ -1 +1 @@ -go1.15rc2 +go1.15.2 diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go index 873a76a..77bfc11 100644 --- a/libgo/go/cmd/go/internal/test/test.go +++ b/libgo/go/cmd/go/internal/test/test.go @@ -1079,9 +1079,13 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error { } var stdout io.Writer = os.Stdout + var err error if testJSON { json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp) - defer json.Close() + defer func() { + json.Exited(err) + json.Close() + }() stdout = json } @@ -1185,7 +1189,7 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error { } t0 := time.Now() - err := cmd.Start() + err = cmd.Start() // This is a last-ditch deadline to detect and // stop wedged test binaries, to keep the builders diff --git a/libgo/go/cmd/go/internal/test/testflag.go b/libgo/go/cmd/go/internal/test/testflag.go index 1ff34f7..4f0a892 100644 --- a/libgo/go/cmd/go/internal/test/testflag.go +++ b/libgo/go/cmd/go/internal/test/testflag.go @@ -214,9 +214,13 @@ func testFlags(args []string) (packageNames, passToTest []string) { explicitArgs := make([]string, 0, len(args)) inPkgList := false + afterFlagWithoutValue := false for len(args) > 0 { f, remainingArgs, err := cmdflag.ParseOne(&CmdTest.Flag, args) + wasAfterFlagWithoutValue := afterFlagWithoutValue + afterFlagWithoutValue = false // provisionally + if errors.Is(err, flag.ErrHelp) { exitWithUsage() } @@ -233,10 +237,24 @@ func testFlags(args []string) (packageNames, passToTest []string) { if nf := (cmdflag.NonFlagError{}); errors.As(err, &nf) { if !inPkgList && packageNames != nil { // We already saw the package list previously, and this argument is not - // a flag, so it — and everything after it — must be a literal argument - // to the test binary. - explicitArgs = append(explicitArgs, args...) - break + // a flag, so it — and everything after it — must be either a value for + // a preceding flag or a literal argument to the test binary. + if wasAfterFlagWithoutValue { + // This argument could syntactically be a flag value, so + // optimistically assume that it is and keep looking for go command + // flags after it. + // + // (If we're wrong, we'll at least be consistent with historical + // behavior; see https://golang.org/issue/40763.) + explicitArgs = append(explicitArgs, nf.RawArg) + args = remainingArgs + continue + } else { + // This argument syntactically cannot be a flag value, so it must be a + // positional argument, and so must everything after it. + explicitArgs = append(explicitArgs, args...) + break + } } inPkgList = true @@ -272,6 +290,9 @@ func testFlags(args []string) (packageNames, passToTest []string) { explicitArgs = append(explicitArgs, nd.RawArg) args = remainingArgs + if !nd.HasValue { + afterFlagWithoutValue = true + } continue } diff --git a/libgo/go/cmd/go/testdata/script/test_flags.txt b/libgo/go/cmd/go/testdata/script/test_flags.txt new file mode 100644 index 0000000..63385e6 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/test_flags.txt @@ -0,0 +1,132 @@ +env GO111MODULE=on + +[short] skip + +# Arguments after the flag terminator should be ignored. +# If we pass '-- -test.v', we should not get verbose output +# *and* output from the test should not be echoed. +go test ./x -- -test.v +stdout '\Aok\s+example.com/x\s+[0-9.s]+\n\z' +! stderr . + +# For backward-compatibility with previous releases of the 'go' command, +# arguments that appear after unrecognized flags should not be treated +# as packages, even if they are unambiguously not arguments to flags. +# Even though ./x looks like a package path, the real package should be +# the implicit '.'. +! go test --answer=42 ./x +stderr '^no Go files in .+$' +! stderr '/x' + +# However, *flags* that appear after unrecognized flags should still be +# interpreted as flags, under the (possibly-erroneous) assumption that +# unrecognized flags are non-boolean. + +go test -v -x ./x -timeout 24h -boolflag=true foo -timeout 25h +stdout 'args: foo -timeout 25h' +stdout 'timeout: 24h0m0s$' # -timeout is unambiguously not a flag, so the real flag wins. + +go test -v -x ./x -timeout 24h -boolflag foo -timeout 25h +stdout 'args: foo -test\.timeout=25h0m0s' # For legacy reasons, '-timeout ' is erroneously rewritten to -test.timeout; see https://golang.org/issue/40763. +stdout 'timeout: 24h0m0s$' # Actual flag wins. + +go test -v -x ./x -timeout 24h -stringflag foo -timeout 25h +stdout 'args: $' +stdout 'timeout: 25h0m0s$' # Later flag wins. + +# An explicit '-outputdir=' argument should set test.outputdir +# to the 'go' command's working directory, not zero it out +# for the test binary. +go test -x -coverprofile=cover.out '-outputdir=' ./x +stderr '-test.outputdir=[^ ]' +exists ./cover.out +! exists ./x/cover.out + +# Test flags from GOFLAGS should be forwarded to the test binary, +# with the 'test.' prefix in the GOFLAGS entry... +env GOFLAGS='-test.timeout=24h0m0s -count=1' +go test -v -x ./x +stdout 'timeout: 24h0m0s$' +stderr '-test.count=1' + +# ...or without. +env GOFLAGS='-timeout=24h0m0s -count=1' +go test -v -x ./x +stdout 'timeout: 24h0m0s$' +stderr '-test.count=1' + +# Arguments from the command line should override GOFLAGS... +go test -v -x -timeout=25h0m0s ./x +stdout 'timeout: 25h0m0s$' +stderr '-test.count=1' + +# ...even if they use a different flag name. +go test -v -x -test.timeout=26h0m0s ./x +stdout 'timeout: 26h0m0s$' +stderr '-test\.timeout=26h0m0s' +! stderr 'timeout=24h0m0s' +stderr '-test.count=1' + +# Invalid flags should be reported exactly once. +! go test -covermode=walrus ./x +stderr -count=1 'invalid value "walrus" for flag -covermode: valid modes are .*$' +stderr '^usage: go test .*$' +stderr '^Run ''go help test'' and ''go help testflag'' for details.$' + +# Passing -help to the test binary should show flag help. +go test ./x -args -help +stdout 'usage_message' + +# -covermode, -coverpkg, and -coverprofile should imply -cover +go test -covermode=set ./x +stdout '\s+coverage:\s+' + +go test -coverpkg=encoding/binary ./x +stdout '\s+coverage:\s+' + +go test -coverprofile=cover.out ./x +stdout '\s+coverage:\s+' +exists ./cover.out +rm ./cover.out + +# -*profile and -trace flags should force output to the current working directory +# or -outputdir, not the directory containing the test. + +go test -memprofile=mem.out ./x +exists ./mem.out +rm ./mem.out + +go test -trace=trace.out ./x +exists ./trace.out +rm ./trace.out + +# Relative paths with -outputdir should be relative to the go command's working +# directory, not the directory containing the test. +mkdir profiles +go test -memprofile=mem.out -outputdir=./profiles ./x +exists ./profiles/mem.out +rm profiles + +-- go.mod -- +module example.com +go 1.14 +-- x/x_test.go -- +package x + +import ( + "flag" + "strings" + "testing" +) + +var _ = flag.String("usage_message", "", "dummy flag to check usage message") +var boolflag = flag.Bool("boolflag", false, "ignored boolean flag") +var stringflag = flag.String("stringflag", "", "ignored string flag") + +func TestLogTimeout(t *testing.T) { + t.Logf("timeout: %v", flag.Lookup("test.timeout").Value) +} + +func TestLogArgs(t *testing.T) { + t.Logf("args: %s", strings.Join(flag.Args(), " ")) +} diff --git a/libgo/go/cmd/internal/test2json/test2json.go b/libgo/go/cmd/internal/test2json/test2json.go index f805213..4eb6dd4 100644 --- a/libgo/go/cmd/internal/test2json/test2json.go +++ b/libgo/go/cmd/internal/test2json/test2json.go @@ -45,10 +45,10 @@ type textBytes []byte func (b textBytes) MarshalText() ([]byte, error) { return b, nil } -// A converter holds the state of a test-to-JSON conversion. +// A Converter holds the state of a test-to-JSON conversion. // It implements io.WriteCloser; the caller writes test output in, // and the converter writes JSON output to w. -type converter struct { +type Converter struct { w io.Writer // JSON output stream pkg string // package to name in events mode Mode // mode bits @@ -100,9 +100,9 @@ var ( // // The pkg string, if present, specifies the import path to // report in the JSON stream. -func NewConverter(w io.Writer, pkg string, mode Mode) io.WriteCloser { - c := new(converter) - *c = converter{ +func NewConverter(w io.Writer, pkg string, mode Mode) *Converter { + c := new(Converter) + *c = Converter{ w: w, pkg: pkg, mode: mode, @@ -122,15 +122,31 @@ func NewConverter(w io.Writer, pkg string, mode Mode) io.WriteCloser { } // Write writes the test input to the converter. -func (c *converter) Write(b []byte) (int, error) { +func (c *Converter) Write(b []byte) (int, error) { c.input.write(b) return len(b), nil } +// Exited marks the test process as having exited with the given error. +func (c *Converter) Exited(err error) { + if err == nil { + c.result = "pass" + } else { + c.result = "fail" + } +} + var ( + // printed by test on successful run. bigPass = []byte("PASS\n") + + // printed by test after a normal test failure. bigFail = []byte("FAIL\n") + // printed by 'go test' along with an error if the test binary terminates + // with an error. + bigFailErrorPrefix = []byte("FAIL\t") + updates = [][]byte{ []byte("=== RUN "), []byte("=== PAUSE "), @@ -153,9 +169,9 @@ var ( // handleInputLine handles a single whole test output line. // It must write the line to c.output but may choose to do so // before or after emitting other events. -func (c *converter) handleInputLine(line []byte) { +func (c *Converter) handleInputLine(line []byte) { // Final PASS or FAIL. - if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) { + if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) || bytes.HasPrefix(line, bigFailErrorPrefix) { c.flushReport(0) c.output.write(line) if bytes.Equal(line, bigPass) { @@ -204,8 +220,18 @@ func (c *converter) handleInputLine(line []byte) { } } + // Not a special test output line. if !ok { - // Not a special test output line. + // Lookup the name of the test which produced the output using the + // indentation of the output as an index into the stack of the current + // subtests. + // If the indentation is greater than the number of current subtests + // then the output must have included extra indentation. We can't + // determine which subtest produced this output, so we default to the + // old behaviour of assuming the most recently run subtest produced it. + if indent > 0 && indent <= len(c.report) { + c.testName = c.report[indent-1].Test + } c.output.write(origLine) return } @@ -269,7 +295,7 @@ func (c *converter) handleInputLine(line []byte) { } // flushReport flushes all pending PASS/FAIL reports at levels >= depth. -func (c *converter) flushReport(depth int) { +func (c *Converter) flushReport(depth int) { c.testName = "" for len(c.report) > depth { e := c.report[len(c.report)-1] @@ -281,23 +307,22 @@ func (c *converter) flushReport(depth int) { // Close marks the end of the go test output. // It flushes any pending input and then output (only partial lines at this point) // and then emits the final overall package-level pass/fail event. -func (c *converter) Close() error { +func (c *Converter) Close() error { c.input.flush() c.output.flush() - e := &event{Action: "fail"} if c.result != "" { - e.Action = c.result - } - if c.mode&Timestamp != 0 { - dt := time.Since(c.start).Round(1 * time.Millisecond).Seconds() - e.Elapsed = &dt + e := &event{Action: c.result} + if c.mode&Timestamp != 0 { + dt := time.Since(c.start).Round(1 * time.Millisecond).Seconds() + e.Elapsed = &dt + } + c.writeEvent(e) } - c.writeEvent(e) return nil } // writeOutputEvent writes a single output event with the given bytes. -func (c *converter) writeOutputEvent(out []byte) { +func (c *Converter) writeOutputEvent(out []byte) { c.writeEvent(&event{ Action: "output", Output: (*textBytes)(&out), @@ -306,7 +331,7 @@ func (c *converter) writeOutputEvent(out []byte) { // writeEvent writes a single event. // It adds the package, time (if requested), and test name (if needed). -func (c *converter) writeEvent(e *event) { +func (c *Converter) writeEvent(e *event) { e.Package = c.pkg if c.mode&Timestamp != 0 { t := time.Now() diff --git a/libgo/go/cmd/internal/test2json/testdata/benchshort.json b/libgo/go/cmd/internal/test2json/testdata/benchshort.json index 8c61d95..34b03b9 100644 --- a/libgo/go/cmd/internal/test2json/testdata/benchshort.json +++ b/libgo/go/cmd/internal/test2json/testdata/benchshort.json @@ -4,4 +4,3 @@ {"Action":"output","Output":"# but to avoid questions of timing, we just use a file with no \\n at all.\n"} {"Action":"output","Output":"BenchmarkFoo \t"} {"Action":"output","Output":"10000 early EOF"} -{"Action":"fail"} diff --git a/libgo/go/cmd/internal/test2json/testdata/empty.json b/libgo/go/cmd/internal/test2json/testdata/empty.json new file mode 100644 index 0000000..e69de29 diff --git a/libgo/go/cmd/internal/test2json/testdata/empty.test b/libgo/go/cmd/internal/test2json/testdata/empty.test new file mode 100644 index 0000000..e69de29 diff --git a/libgo/go/cmd/internal/test2json/testdata/issue29755.json b/libgo/go/cmd/internal/test2json/testdata/issue29755.json new file mode 100644 index 0000000..2e8ba48 --- /dev/null +++ b/libgo/go/cmd/internal/test2json/testdata/issue29755.json @@ -0,0 +1,38 @@ +{"Action":"run","Test":"TestOutputWithSubtest"} +{"Action":"output","Test":"TestOutputWithSubtest","Output":"=== RUN TestOutputWithSubtest\n"} +{"Action":"run","Test":"TestOutputWithSubtest/sub_test"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":"=== RUN TestOutputWithSubtest/sub_test\n"} +{"Action":"run","Test":"TestOutputWithSubtest/sub_test/sub2"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test/sub2","Output":"=== RUN TestOutputWithSubtest/sub_test/sub2\n"} +{"Action":"run","Test":"TestOutputWithSubtest/sub_test2"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":"=== RUN TestOutputWithSubtest/sub_test2\n"} +{"Action":"run","Test":"TestOutputWithSubtest/sub_test2/sub2"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test2/sub2","Output":"=== RUN TestOutputWithSubtest/sub_test2/sub2\n"} +{"Action":"output","Test":"TestOutputWithSubtest","Output":"--- FAIL: TestOutputWithSubtest (0.00s)\n"} +{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:6: output before sub tests\n"} +{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:10: output from root test\n"} +{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:15: output from root test\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":" --- PASS: TestOutputWithSubtest/sub_test (0.00s)\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":" foo_test.go:9: output from sub test\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":" foo_test.go:11: more output from sub test\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test","Output":" foo_test.go:16: more output from sub test\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test/sub2","Output":" --- PASS: TestOutputWithSubtest/sub_test/sub2 (0.00s)\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test/sub2","Output":" foo_test.go:14: output from sub2 test\n"} +{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:22: output from root test\n"} +{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:27: output from root test\n"} +{"Action":"pass","Test":"TestOutputWithSubtest/sub_test/sub2"} +{"Action":"pass","Test":"TestOutputWithSubtest/sub_test"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":" --- PASS: TestOutputWithSubtest/sub_test2 (0.00s)\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":" foo_test.go:21: output from sub test2\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":" foo_test.go:23: more output from sub test2\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test2","Output":" foo_test.go:28: more output from sub test2\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test2/sub2","Output":" --- PASS: TestOutputWithSubtest/sub_test2/sub2 (0.00s)\n"} +{"Action":"output","Test":"TestOutputWithSubtest/sub_test2/sub2","Output":" foo_test.go:26: output from sub2 test\n"} +{"Action":"output","Test":"TestOutputWithSubtest","Output":" foo_test.go:32: output after sub test\n"} +{"Action":"pass","Test":"TestOutputWithSubtest/sub_test2/sub2"} +{"Action":"pass","Test":"TestOutputWithSubtest/sub_test2"} +{"Action":"fail","Test":"TestOutputWithSubtest"} +{"Action":"output","Output":"FAIL\n"} +{"Action":"output","Output":"FAIL\tgotest.tools/gotestsum/foo\t0.001s\n"} +{"Action":"output","Output":"FAIL\n"} +{"Action":"fail"} diff --git a/libgo/go/cmd/internal/test2json/testdata/issue29755.test b/libgo/go/cmd/internal/test2json/testdata/issue29755.test new file mode 100644 index 0000000..b0c596c --- /dev/null +++ b/libgo/go/cmd/internal/test2json/testdata/issue29755.test @@ -0,0 +1,27 @@ +=== RUN TestOutputWithSubtest +=== RUN TestOutputWithSubtest/sub_test +=== RUN TestOutputWithSubtest/sub_test/sub2 +=== RUN TestOutputWithSubtest/sub_test2 +=== RUN TestOutputWithSubtest/sub_test2/sub2 +--- FAIL: TestOutputWithSubtest (0.00s) + foo_test.go:6: output before sub tests + foo_test.go:10: output from root test + foo_test.go:15: output from root test + --- PASS: TestOutputWithSubtest/sub_test (0.00s) + foo_test.go:9: output from sub test + foo_test.go:11: more output from sub test + foo_test.go:16: more output from sub test + --- PASS: TestOutputWithSubtest/sub_test/sub2 (0.00s) + foo_test.go:14: output from sub2 test + foo_test.go:22: output from root test + foo_test.go:27: output from root test + --- PASS: TestOutputWithSubtest/sub_test2 (0.00s) + foo_test.go:21: output from sub test2 + foo_test.go:23: more output from sub test2 + foo_test.go:28: more output from sub test2 + --- PASS: TestOutputWithSubtest/sub_test2/sub2 (0.00s) + foo_test.go:26: output from sub2 test + foo_test.go:32: output after sub test +FAIL +FAIL gotest.tools/gotestsum/foo 0.001s +FAIL diff --git a/libgo/go/cmd/internal/test2json/testdata/panic.json b/libgo/go/cmd/internal/test2json/testdata/panic.json new file mode 100644 index 0000000..f773814 --- /dev/null +++ b/libgo/go/cmd/internal/test2json/testdata/panic.json @@ -0,0 +1,19 @@ +{"Action":"output","Test":"TestPanic","Output":"--- FAIL: TestPanic (0.00s)\n"} +{"Action":"output","Test":"TestPanic","Output":"panic: oops [recovered]\n"} +{"Action":"output","Test":"TestPanic","Output":"\tpanic: oops\n"} +{"Action":"output","Test":"TestPanic","Output":"\n"} +{"Action":"output","Test":"TestPanic","Output":"goroutine 7 [running]:\n"} +{"Action":"output","Test":"TestPanic","Output":"testing.tRunner.func1(0xc000092100)\n"} +{"Action":"output","Test":"TestPanic","Output":"\t/go/src/testing/testing.go:874 +0x3a3\n"} +{"Action":"output","Test":"TestPanic","Output":"panic(0x1110ea0, 0x116aea0)\n"} +{"Action":"output","Test":"TestPanic","Output":"\t/go/src/runtime/panic.go:679 +0x1b2\n"} +{"Action":"output","Test":"TestPanic","Output":"command-line-arguments.TestPanic(0xc000092100)\n"} +{"Action":"output","Test":"TestPanic","Output":"\ta_test.go:6 +0x39\n"} +{"Action":"output","Test":"TestPanic","Output":"testing.tRunner(0xc000092100, 0x114f500)\n"} +{"Action":"output","Test":"TestPanic","Output":"\tgo/src/testing/testing.go:909 +0xc9\n"} +{"Action":"output","Test":"TestPanic","Output":"created by testing.(*T).Run\n"} +{"Action":"output","Test":"TestPanic","Output":"\tgo/src/testing/testing.go:960 +0x350\n"} +{"Action":"fail","Test":"TestPanic"} +{"Action":"output","Output":"FAIL\tcommand-line-arguments\t0.042s\n"} +{"Action":"output","Output":"FAIL\n"} +{"Action":"fail"} diff --git a/libgo/go/cmd/internal/test2json/testdata/panic.test b/libgo/go/cmd/internal/test2json/testdata/panic.test new file mode 100644 index 0000000..517ebaf --- /dev/null +++ b/libgo/go/cmd/internal/test2json/testdata/panic.test @@ -0,0 +1,17 @@ +--- FAIL: TestPanic (0.00s) +panic: oops [recovered] + panic: oops + +goroutine 7 [running]: +testing.tRunner.func1(0xc000092100) + /go/src/testing/testing.go:874 +0x3a3 +panic(0x1110ea0, 0x116aea0) + /go/src/runtime/panic.go:679 +0x1b2 +command-line-arguments.TestPanic(0xc000092100) + a_test.go:6 +0x39 +testing.tRunner(0xc000092100, 0x114f500) + go/src/testing/testing.go:909 +0xc9 +created by testing.(*T).Run + go/src/testing/testing.go:960 +0x350 +FAIL command-line-arguments 0.042s +FAIL diff --git a/libgo/go/cmd/internal/test2json/testdata/smiley.json b/libgo/go/cmd/internal/test2json/testdata/smiley.json index afa990d..f49180d 100644 --- a/libgo/go/cmd/internal/test2json/testdata/smiley.json +++ b/libgo/go/cmd/internal/test2json/testdata/smiley.json @@ -116,13 +116,13 @@ {"Action":"output","Test":"Test☺☹/2","Output":"=== CONT Test☺☹/2\n"} {"Action":"output","Test":"TestTags","Output":"--- PASS: TestTags (0.00s)\n"} {"Action":"output","Test":"TestTags/x_testtag_y","Output":" --- PASS: TestTags/x_testtag_y (0.04s)\n"} -{"Action":"output","Test":"TestTags/x_testtag_y","Output":" \tvet_test.go:187: -tags=x testtag y\n"} +{"Action":"output","Test":"TestTags/x_testtag_y","Output":" vet_test.go:187: -tags=x testtag y\n"} {"Action":"pass","Test":"TestTags/x_testtag_y"} {"Action":"output","Test":"TestTags/x,testtag,y","Output":" --- PASS: TestTags/x,testtag,y (0.04s)\n"} -{"Action":"output","Test":"TestTags/x,testtag,y","Output":" \tvet_test.go:187: -tags=x,testtag,y\n"} +{"Action":"output","Test":"TestTags/x,testtag,y","Output":" vet_test.go:187: -tags=x,testtag,y\n"} {"Action":"pass","Test":"TestTags/x,testtag,y"} {"Action":"output","Test":"TestTags/testtag","Output":" --- PASS: TestTags/testtag (0.04s)\n"} -{"Action":"output","Test":"TestTags/testtag","Output":" \tvet_test.go:187: -tags=testtag\n"} +{"Action":"output","Test":"TestTags/testtag","Output":" vet_test.go:187: -tags=testtag\n"} {"Action":"pass","Test":"TestTags/testtag"} {"Action":"pass","Test":"TestTags"} {"Action":"cont","Test":"Test☺☹/1"} @@ -139,28 +139,28 @@ {"Action":"output","Test":"Test☺☹Dirs/cgo","Output":"=== CONT Test☺☹Dirs/cgo\n"} {"Action":"output","Test":"Test☺☹","Output":"--- PASS: Test☺☹ (0.39s)\n"} {"Action":"output","Test":"Test☺☹/5","Output":" --- PASS: Test☺☹/5 (0.07s)\n"} -{"Action":"output","Test":"Test☺☹/5","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"} +{"Action":"output","Test":"Test☺☹/5","Output":" vet_test.go:114: φιλεσ: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"} {"Action":"pass","Test":"Test☺☹/5"} {"Action":"output","Test":"Test☺☹/3","Output":" --- PASS: Test☺☹/3 (0.07s)\n"} -{"Action":"output","Test":"Test☺☹/3","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"} +{"Action":"output","Test":"Test☺☹/3","Output":" vet_test.go:114: φιλεσ: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"} {"Action":"pass","Test":"Test☺☹/3"} {"Action":"output","Test":"Test☺☹/6","Output":" --- PASS: Test☺☹/6 (0.07s)\n"} -{"Action":"output","Test":"Test☺☹/6","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"} +{"Action":"output","Test":"Test☺☹/6","Output":" vet_test.go:114: φιλεσ: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"} {"Action":"pass","Test":"Test☺☹/6"} {"Action":"output","Test":"Test☺☹/2","Output":" --- PASS: Test☺☹/2 (0.07s)\n"} -{"Action":"output","Test":"Test☺☹/2","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"} +{"Action":"output","Test":"Test☺☹/2","Output":" vet_test.go:114: φιλεσ: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"} {"Action":"pass","Test":"Test☺☹/2"} {"Action":"output","Test":"Test☺☹/0","Output":" --- PASS: Test☺☹/0 (0.13s)\n"} -{"Action":"output","Test":"Test☺☹/0","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"} +{"Action":"output","Test":"Test☺☹/0","Output":" vet_test.go:114: φιλεσ: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"} {"Action":"pass","Test":"Test☺☹/0"} {"Action":"output","Test":"Test☺☹/4","Output":" --- PASS: Test☺☹/4 (0.16s)\n"} -{"Action":"output","Test":"Test☺☹/4","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"} +{"Action":"output","Test":"Test☺☹/4","Output":" vet_test.go:114: φιλεσ: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"} {"Action":"pass","Test":"Test☺☹/4"} {"Action":"output","Test":"Test☺☹/1","Output":" --- PASS: Test☺☹/1 (0.07s)\n"} -{"Action":"output","Test":"Test☺☹/1","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"} +{"Action":"output","Test":"Test☺☹/1","Output":" vet_test.go:114: φιλεσ: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"} {"Action":"pass","Test":"Test☺☹/1"} {"Action":"output","Test":"Test☺☹/7","Output":" --- PASS: Test☺☹/7 (0.19s)\n"} -{"Action":"output","Test":"Test☺☹/7","Output":" \tvet_test.go:114: φιλεσ: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"} +{"Action":"output","Test":"Test☺☹/7","Output":" vet_test.go:114: φιλεσ: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"} {"Action":"pass","Test":"Test☺☹/7"} {"Action":"pass","Test":"Test☺☹"} {"Action":"output","Test":"Test☺☹Dirs","Output":"--- PASS: Test☺☹Dirs (0.01s)\n"} diff --git a/libgo/go/cmd/internal/test2json/testdata/smiley.test b/libgo/go/cmd/internal/test2json/testdata/smiley.test index 05edf5a..bd1ed2d 100644 --- a/libgo/go/cmd/internal/test2json/testdata/smiley.test +++ b/libgo/go/cmd/internal/test2json/testdata/smiley.test @@ -58,11 +58,11 @@ === CONT Test☺☹/2 --- PASS: TestTags (0.00s) --- PASS: TestTags/x_testtag_y (0.04s) - vet_test.go:187: -tags=x testtag y + vet_test.go:187: -tags=x testtag y --- PASS: TestTags/x,testtag,y (0.04s) - vet_test.go:187: -tags=x,testtag,y + vet_test.go:187: -tags=x,testtag,y --- PASS: TestTags/testtag (0.04s) - vet_test.go:187: -tags=testtag + vet_test.go:187: -tags=testtag === CONT Test☺☹/1 === CONT Test☺☹Dirs/testingpkg === CONT Test☺☹Dirs/buildtag @@ -71,21 +71,21 @@ === CONT Test☺☹Dirs/cgo --- PASS: Test☺☹ (0.39s) --- PASS: Test☺☹/5 (0.07s) - vet_test.go:114: φιλεσ: ["testdata/copylock_func.go" "testdata/rangeloop.go"] + vet_test.go:114: φιλεσ: ["testdata/copylock_func.go" "testdata/rangeloop.go"] --- PASS: Test☺☹/3 (0.07s) - vet_test.go:114: φιλεσ: ["testdata/composite.go" "testdata/nilfunc.go"] + vet_test.go:114: φιλεσ: ["testdata/composite.go" "testdata/nilfunc.go"] --- PASS: Test☺☹/6 (0.07s) - vet_test.go:114: φιλεσ: ["testdata/copylock_range.go" "testdata/shadow.go"] + vet_test.go:114: φιλεσ: ["testdata/copylock_range.go" "testdata/shadow.go"] --- PASS: Test☺☹/2 (0.07s) - vet_test.go:114: φιλεσ: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"] + vet_test.go:114: φιλεσ: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"] --- PASS: Test☺☹/0 (0.13s) - vet_test.go:114: φιλεσ: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"] + vet_test.go:114: φιλεσ: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"] --- PASS: Test☺☹/4 (0.16s) - vet_test.go:114: φιλεσ: ["testdata/copylock.go" "testdata/print.go"] + vet_test.go:114: φιλεσ: ["testdata/copylock.go" "testdata/print.go"] --- PASS: Test☺☹/1 (0.07s) - vet_test.go:114: φιλεσ: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"] + vet_test.go:114: φιλεσ: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"] --- PASS: Test☺☹/7 (0.19s) - vet_test.go:114: φιλεσ: ["testdata/deadcode.go" "testdata/shift.go"] + vet_test.go:114: φιλεσ: ["testdata/deadcode.go" "testdata/shift.go"] --- PASS: Test☺☹Dirs (0.01s) --- PASS: Test☺☹Dirs/testingpkg (0.06s) --- PASS: Test☺☹Dirs/divergent (0.05s) diff --git a/libgo/go/cmd/internal/test2json/testdata/vet.json b/libgo/go/cmd/internal/test2json/testdata/vet.json index 8c5921d..2558d61 100644 --- a/libgo/go/cmd/internal/test2json/testdata/vet.json +++ b/libgo/go/cmd/internal/test2json/testdata/vet.json @@ -116,13 +116,13 @@ {"Action":"output","Test":"TestVet/2","Output":"=== CONT TestVet/2\n"} {"Action":"output","Test":"TestTags","Output":"--- PASS: TestTags (0.00s)\n"} {"Action":"output","Test":"TestTags/x_testtag_y","Output":" --- PASS: TestTags/x_testtag_y (0.04s)\n"} -{"Action":"output","Test":"TestTags/x_testtag_y","Output":" \tvet_test.go:187: -tags=x testtag y\n"} +{"Action":"output","Test":"TestTags/x_testtag_y","Output":" vet_test.go:187: -tags=x testtag y\n"} {"Action":"pass","Test":"TestTags/x_testtag_y"} {"Action":"output","Test":"TestTags/x,testtag,y","Output":" --- PASS: TestTags/x,testtag,y (0.04s)\n"} -{"Action":"output","Test":"TestTags/x,testtag,y","Output":" \tvet_test.go:187: -tags=x,testtag,y\n"} +{"Action":"output","Test":"TestTags/x,testtag,y","Output":" vet_test.go:187: -tags=x,testtag,y\n"} {"Action":"pass","Test":"TestTags/x,testtag,y"} {"Action":"output","Test":"TestTags/testtag","Output":" --- PASS: TestTags/testtag (0.04s)\n"} -{"Action":"output","Test":"TestTags/testtag","Output":" \tvet_test.go:187: -tags=testtag\n"} +{"Action":"output","Test":"TestTags/testtag","Output":" vet_test.go:187: -tags=testtag\n"} {"Action":"pass","Test":"TestTags/testtag"} {"Action":"pass","Test":"TestTags"} {"Action":"cont","Test":"TestVet/1"} @@ -139,28 +139,28 @@ {"Action":"output","Test":"TestVetDirs/cgo","Output":"=== CONT TestVetDirs/cgo\n"} {"Action":"output","Test":"TestVet","Output":"--- PASS: TestVet (0.39s)\n"} {"Action":"output","Test":"TestVet/5","Output":" --- PASS: TestVet/5 (0.07s)\n"} -{"Action":"output","Test":"TestVet/5","Output":" \tvet_test.go:114: files: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"} +{"Action":"output","Test":"TestVet/5","Output":" vet_test.go:114: files: [\"testdata/copylock_func.go\" \"testdata/rangeloop.go\"]\n"} {"Action":"pass","Test":"TestVet/5"} {"Action":"output","Test":"TestVet/3","Output":" --- PASS: TestVet/3 (0.07s)\n"} -{"Action":"output","Test":"TestVet/3","Output":" \tvet_test.go:114: files: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"} +{"Action":"output","Test":"TestVet/3","Output":" vet_test.go:114: files: [\"testdata/composite.go\" \"testdata/nilfunc.go\"]\n"} {"Action":"pass","Test":"TestVet/3"} {"Action":"output","Test":"TestVet/6","Output":" --- PASS: TestVet/6 (0.07s)\n"} -{"Action":"output","Test":"TestVet/6","Output":" \tvet_test.go:114: files: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"} +{"Action":"output","Test":"TestVet/6","Output":" vet_test.go:114: files: [\"testdata/copylock_range.go\" \"testdata/shadow.go\"]\n"} {"Action":"pass","Test":"TestVet/6"} {"Action":"output","Test":"TestVet/2","Output":" --- PASS: TestVet/2 (0.07s)\n"} -{"Action":"output","Test":"TestVet/2","Output":" \tvet_test.go:114: files: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"} +{"Action":"output","Test":"TestVet/2","Output":" vet_test.go:114: files: [\"testdata/bool.go\" \"testdata/method.go\" \"testdata/unused.go\"]\n"} {"Action":"pass","Test":"TestVet/2"} {"Action":"output","Test":"TestVet/0","Output":" --- PASS: TestVet/0 (0.13s)\n"} -{"Action":"output","Test":"TestVet/0","Output":" \tvet_test.go:114: files: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"} +{"Action":"output","Test":"TestVet/0","Output":" vet_test.go:114: files: [\"testdata/assign.go\" \"testdata/httpresponse.go\" \"testdata/structtag.go\"]\n"} {"Action":"pass","Test":"TestVet/0"} {"Action":"output","Test":"TestVet/4","Output":" --- PASS: TestVet/4 (0.16s)\n"} -{"Action":"output","Test":"TestVet/4","Output":" \tvet_test.go:114: files: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"} +{"Action":"output","Test":"TestVet/4","Output":" vet_test.go:114: files: [\"testdata/copylock.go\" \"testdata/print.go\"]\n"} {"Action":"pass","Test":"TestVet/4"} {"Action":"output","Test":"TestVet/1","Output":" --- PASS: TestVet/1 (0.07s)\n"} -{"Action":"output","Test":"TestVet/1","Output":" \tvet_test.go:114: files: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"} +{"Action":"output","Test":"TestVet/1","Output":" vet_test.go:114: files: [\"testdata/atomic.go\" \"testdata/lostcancel.go\" \"testdata/unsafeptr.go\"]\n"} {"Action":"pass","Test":"TestVet/1"} {"Action":"output","Test":"TestVet/7","Output":" --- PASS: TestVet/7 (0.19s)\n"} -{"Action":"output","Test":"TestVet/7","Output":" \tvet_test.go:114: files: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"} +{"Action":"output","Test":"TestVet/7","Output":" vet_test.go:114: files: [\"testdata/deadcode.go\" \"testdata/shift.go\"]\n"} {"Action":"pass","Test":"TestVet/7"} {"Action":"pass","Test":"TestVet"} {"Action":"output","Test":"TestVetDirs","Output":"--- PASS: TestVetDirs (0.01s)\n"} diff --git a/libgo/go/cmd/internal/test2json/testdata/vet.test b/libgo/go/cmd/internal/test2json/testdata/vet.test index 3389559..59d187e 100644 --- a/libgo/go/cmd/internal/test2json/testdata/vet.test +++ b/libgo/go/cmd/internal/test2json/testdata/vet.test @@ -58,11 +58,11 @@ === CONT TestVet/2 --- PASS: TestTags (0.00s) --- PASS: TestTags/x_testtag_y (0.04s) - vet_test.go:187: -tags=x testtag y + vet_test.go:187: -tags=x testtag y --- PASS: TestTags/x,testtag,y (0.04s) - vet_test.go:187: -tags=x,testtag,y + vet_test.go:187: -tags=x,testtag,y --- PASS: TestTags/testtag (0.04s) - vet_test.go:187: -tags=testtag + vet_test.go:187: -tags=testtag === CONT TestVet/1 === CONT TestVetDirs/testingpkg === CONT TestVetDirs/buildtag @@ -71,21 +71,21 @@ === CONT TestVetDirs/cgo --- PASS: TestVet (0.39s) --- PASS: TestVet/5 (0.07s) - vet_test.go:114: files: ["testdata/copylock_func.go" "testdata/rangeloop.go"] + vet_test.go:114: files: ["testdata/copylock_func.go" "testdata/rangeloop.go"] --- PASS: TestVet/3 (0.07s) - vet_test.go:114: files: ["testdata/composite.go" "testdata/nilfunc.go"] + vet_test.go:114: files: ["testdata/composite.go" "testdata/nilfunc.go"] --- PASS: TestVet/6 (0.07s) - vet_test.go:114: files: ["testdata/copylock_range.go" "testdata/shadow.go"] + vet_test.go:114: files: ["testdata/copylock_range.go" "testdata/shadow.go"] --- PASS: TestVet/2 (0.07s) - vet_test.go:114: files: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"] + vet_test.go:114: files: ["testdata/bool.go" "testdata/method.go" "testdata/unused.go"] --- PASS: TestVet/0 (0.13s) - vet_test.go:114: files: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"] + vet_test.go:114: files: ["testdata/assign.go" "testdata/httpresponse.go" "testdata/structtag.go"] --- PASS: TestVet/4 (0.16s) - vet_test.go:114: files: ["testdata/copylock.go" "testdata/print.go"] + vet_test.go:114: files: ["testdata/copylock.go" "testdata/print.go"] --- PASS: TestVet/1 (0.07s) - vet_test.go:114: files: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"] + vet_test.go:114: files: ["testdata/atomic.go" "testdata/lostcancel.go" "testdata/unsafeptr.go"] --- PASS: TestVet/7 (0.19s) - vet_test.go:114: files: ["testdata/deadcode.go" "testdata/shift.go"] + vet_test.go:114: files: ["testdata/deadcode.go" "testdata/shift.go"] --- PASS: TestVetDirs (0.01s) --- PASS: TestVetDirs/testingpkg (0.06s) --- PASS: TestVetDirs/divergent (0.05s) diff --git a/libgo/go/cmd/test2json/main.go b/libgo/go/cmd/test2json/main.go index 0385d8f2..57a8741 100644 --- a/libgo/go/cmd/test2json/main.go +++ b/libgo/go/cmd/test2json/main.go @@ -118,12 +118,16 @@ func main() { w := &countWriter{0, c} cmd.Stdout = w cmd.Stderr = w - if err := cmd.Run(); err != nil { + err := cmd.Run() + if err != nil { if w.n > 0 { // Assume command printed why it failed. } else { fmt.Fprintf(c, "test2json: %v\n", err) } + } + c.Exited(err) + if err != nil { c.Close() os.Exit(1) } diff --git a/libgo/go/internal/poll/copy_file_range_linux.go b/libgo/go/internal/poll/copy_file_range_linux.go index 604607f..09de299 100644 --- a/libgo/go/internal/poll/copy_file_range_linux.go +++ b/libgo/go/internal/poll/copy_file_range_linux.go @@ -41,7 +41,7 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err // use copy_file_range(2) again. atomic.StoreInt32(©FileRangeSupported, 0) return 0, false, nil - case syscall.EXDEV, syscall.EINVAL: + case syscall.EXDEV, syscall.EINVAL, syscall.EOPNOTSUPP, syscall.EPERM: // Prior to Linux 5.3, it was not possible to // copy_file_range across file systems. Similarly to // the ENOSYS case above, if we see EXDEV, we have @@ -52,6 +52,14 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err // dst or src refer to a pipe rather than a regular // file. This is another case where no data has been // transfered, so we consider it unhandled. + // + // If the file is on NFS, we can see EOPNOTSUPP. + // See issue #40731. + // + // If the process is running inside a Docker container, + // we might see EPERM instead of ENOSYS. See issue + // #40893. Since EPERM might also be a legitimate error, + // don't mark copy_file_range(2) as unsupported. return 0, false, nil case nil: if n == 0 { diff --git a/libgo/go/net/http/cgi/child.go b/libgo/go/net/http/cgi/child.go index 9474175..61de616 100644 --- a/libgo/go/net/http/cgi/child.go +++ b/libgo/go/net/http/cgi/child.go @@ -163,10 +163,12 @@ func Serve(handler http.Handler) error { } type response struct { - req *http.Request - header http.Header - bufw *bufio.Writer - headerSent bool + req *http.Request + header http.Header + code int + wroteHeader bool + wroteCGIHeader bool + bufw *bufio.Writer } func (r *response) Flush() { @@ -178,26 +180,38 @@ func (r *response) Header() http.Header { } func (r *response) Write(p []byte) (n int, err error) { - if !r.headerSent { + if !r.wroteHeader { r.WriteHeader(http.StatusOK) } + if !r.wroteCGIHeader { + r.writeCGIHeader(p) + } return r.bufw.Write(p) } func (r *response) WriteHeader(code int) { - if r.headerSent { + if r.wroteHeader { // Note: explicitly using Stderr, as Stdout is our HTTP output. fmt.Fprintf(os.Stderr, "CGI attempted to write header twice on request for %s", r.req.URL) return } - r.headerSent = true - fmt.Fprintf(r.bufw, "Status: %d %s\r\n", code, http.StatusText(code)) + r.wroteHeader = true + r.code = code +} - // Set a default Content-Type +// writeCGIHeader finalizes the header sent to the client and writes it to the output. +// p is not written by writeHeader, but is the first chunk of the body +// that will be written. It is sniffed for a Content-Type if none is +// set explicitly. +func (r *response) writeCGIHeader(p []byte) { + if r.wroteCGIHeader { + return + } + r.wroteCGIHeader = true + fmt.Fprintf(r.bufw, "Status: %d %s\r\n", r.code, http.StatusText(r.code)) if _, hasType := r.header["Content-Type"]; !hasType { - r.header.Add("Content-Type", "text/html; charset=utf-8") + r.header.Set("Content-Type", http.DetectContentType(p)) } - r.header.Write(r.bufw) r.bufw.WriteString("\r\n") r.bufw.Flush() diff --git a/libgo/go/net/http/cgi/child_test.go b/libgo/go/net/http/cgi/child_test.go index 14e0af4..f6ecb6e 100644 --- a/libgo/go/net/http/cgi/child_test.go +++ b/libgo/go/net/http/cgi/child_test.go @@ -7,6 +7,11 @@ package cgi import ( + "bufio" + "bytes" + "net/http" + "net/http/httptest" + "strings" "testing" ) @@ -148,3 +153,67 @@ func TestRequestWithoutRemotePort(t *testing.T) { t.Errorf("RemoteAddr: got %q; want %q", g, e) } } + +type countingWriter int + +func (c *countingWriter) Write(p []byte) (int, error) { + *c += countingWriter(len(p)) + return len(p), nil +} +func (c *countingWriter) WriteString(p string) (int, error) { + *c += countingWriter(len(p)) + return len(p), nil +} + +func TestResponse(t *testing.T) { + var tests = []struct { + name string + body string + wantCT string + }{ + { + name: "no body", + wantCT: "text/plain; charset=utf-8", + }, + { + name: "html", + body: "test pageThis is a body", + wantCT: "text/html; charset=utf-8", + }, + { + name: "text", + body: strings.Repeat("gopher", 86), + wantCT: "text/plain; charset=utf-8", + }, + { + name: "jpg", + body: "\xFF\xD8\xFF" + strings.Repeat("B", 1024), + wantCT: "image/jpeg", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var buf bytes.Buffer + resp := response{ + req: httptest.NewRequest("GET", "/", nil), + header: http.Header{}, + bufw: bufio.NewWriter(&buf), + } + n, err := resp.Write([]byte(tt.body)) + if err != nil { + t.Errorf("Write: unexpected %v", err) + } + if want := len(tt.body); n != want { + t.Errorf("reported short Write: got %v want %v", n, want) + } + resp.writeCGIHeader(nil) + resp.Flush() + if got := resp.Header().Get("Content-Type"); got != tt.wantCT { + t.Errorf("wrong content-type: got %q, want %q", got, tt.wantCT) + } + if !bytes.HasSuffix(buf.Bytes(), []byte(tt.body)) { + t.Errorf("body was not correctly written") + } + }) + } +} diff --git a/libgo/go/net/http/cgi/integration_test.go b/libgo/go/net/http/cgi/integration_test.go index 32d59c0..295c3b8 100644 --- a/libgo/go/net/http/cgi/integration_test.go +++ b/libgo/go/net/http/cgi/integration_test.go @@ -16,7 +16,9 @@ import ( "io" "net/http" "net/http/httptest" + "net/url" "os" + "strings" "testing" "time" ) @@ -52,7 +54,7 @@ func TestHostingOurselves(t *testing.T) { } replay := runCgiTest(t, h, "GET /test.go?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n", expectedMap) - if expected, got := "text/html; charset=utf-8", replay.Header().Get("Content-Type"); got != expected { + if expected, got := "text/plain; charset=utf-8", replay.Header().Get("Content-Type"); got != expected { t.Errorf("got a Content-Type of %q; expected %q", got, expected) } if expected, got := "X-Test-Value", replay.Header().Get("X-Test-Header"); got != expected { @@ -152,6 +154,51 @@ func TestChildOnlyHeaders(t *testing.T) { } } +func TestChildContentType(t *testing.T) { + testenv.MustHaveExec(t) + + h := &Handler{ + Path: os.Args[0], + Root: "/test.go", + Args: []string{"-test.run=TestBeChildCGIProcess"}, + } + var tests = []struct { + name string + body string + wantCT string + }{ + { + name: "no body", + wantCT: "text/plain; charset=utf-8", + }, + { + name: "html", + body: "test pageThis is a body", + wantCT: "text/html; charset=utf-8", + }, + { + name: "text", + body: strings.Repeat("gopher", 86), + wantCT: "text/plain; charset=utf-8", + }, + { + name: "jpg", + body: "\xFF\xD8\xFF" + strings.Repeat("B", 1024), + wantCT: "image/jpeg", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + expectedMap := map[string]string{"_body": tt.body} + req := fmt.Sprintf("GET /test.go?exact-body=%s HTTP/1.0\nHost: example.com\n\n", url.QueryEscape(tt.body)) + replay := runCgiTest(t, h, req, expectedMap) + if got := replay.Header().Get("Content-Type"); got != tt.wantCT { + t.Errorf("got a Content-Type of %q; expected it to start with %q", got, tt.wantCT) + } + }) + } +} + // golang.org/issue/7198 func Test500WithNoHeaders(t *testing.T) { want500Test(t, "/immediate-disconnect") } func Test500WithNoContentType(t *testing.T) { want500Test(t, "/no-content-type") } @@ -203,6 +250,10 @@ func TestBeChildCGIProcess(t *testing.T) { if req.FormValue("no-body") == "1" { return } + if eb, ok := req.Form["exact-body"]; ok { + io.WriteString(rw, eb[0]) + return + } if req.FormValue("write-forever") == "1" { io.Copy(rw, neverEnding('a')) for { diff --git a/libgo/go/net/http/fcgi/child.go b/libgo/go/net/http/fcgi/child.go index 30a6b2c..a31273b 100644 --- a/libgo/go/net/http/fcgi/child.go +++ b/libgo/go/net/http/fcgi/child.go @@ -74,10 +74,12 @@ func (r *request) parseParams() { // response implements http.ResponseWriter. type response struct { - req *request - header http.Header - w *bufWriter - wroteHeader bool + req *request + header http.Header + code int + wroteHeader bool + wroteCGIHeader bool + w *bufWriter } func newResponse(c *child, req *request) *response { @@ -92,11 +94,14 @@ func (r *response) Header() http.Header { return r.header } -func (r *response) Write(data []byte) (int, error) { +func (r *response) Write(p []byte) (n int, err error) { if !r.wroteHeader { r.WriteHeader(http.StatusOK) } - return r.w.Write(data) + if !r.wroteCGIHeader { + r.writeCGIHeader(p) + } + return r.w.Write(p) } func (r *response) WriteHeader(code int) { @@ -104,22 +109,34 @@ func (r *response) WriteHeader(code int) { return } r.wroteHeader = true + r.code = code if code == http.StatusNotModified { // Must not have body. r.header.Del("Content-Type") r.header.Del("Content-Length") r.header.Del("Transfer-Encoding") - } else if r.header.Get("Content-Type") == "" { - r.header.Set("Content-Type", "text/html; charset=utf-8") } - if r.header.Get("Date") == "" { r.header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) } +} - fmt.Fprintf(r.w, "Status: %d %s\r\n", code, http.StatusText(code)) +// writeCGIHeader finalizes the header sent to the client and writes it to the output. +// p is not written by writeHeader, but is the first chunk of the body +// that will be written. It is sniffed for a Content-Type if none is +// set explicitly. +func (r *response) writeCGIHeader(p []byte) { + if r.wroteCGIHeader { + return + } + r.wroteCGIHeader = true + fmt.Fprintf(r.w, "Status: %d %s\r\n", r.code, http.StatusText(r.code)) + if _, hasType := r.header["Content-Type"]; r.code != http.StatusNotModified && !hasType { + r.header.Set("Content-Type", http.DetectContentType(p)) + } r.header.Write(r.w) r.w.WriteString("\r\n") + r.w.Flush() } func (r *response) Flush() { @@ -290,6 +307,8 @@ func (c *child) serveRequest(req *request, body io.ReadCloser) { httpReq = httpReq.WithContext(envVarCtx) c.handler.ServeHTTP(r, httpReq) } + // Make sure we serve something even if nothing was written to r + r.Write(nil) r.Close() c.mu.Lock() delete(c.requests, req.reqId) diff --git a/libgo/go/net/http/fcgi/fcgi_test.go b/libgo/go/net/http/fcgi/fcgi_test.go index e9d2b34..59246c2 100644 --- a/libgo/go/net/http/fcgi/fcgi_test.go +++ b/libgo/go/net/http/fcgi/fcgi_test.go @@ -10,6 +10,7 @@ import ( "io" "io/ioutil" "net/http" + "strings" "testing" ) @@ -344,3 +345,55 @@ func TestChildServeReadsEnvVars(t *testing.T) { <-done } } + +func TestResponseWriterSniffsContentType(t *testing.T) { + t.Skip("this test is flaky, see Issue 41167") + var tests = []struct { + name string + body string + wantCT string + }{ + { + name: "no body", + wantCT: "text/plain; charset=utf-8", + }, + { + name: "html", + body: "test pageThis is a body", + wantCT: "text/html; charset=utf-8", + }, + { + name: "text", + body: strings.Repeat("gopher", 86), + wantCT: "text/plain; charset=utf-8", + }, + { + name: "jpg", + body: "\xFF\xD8\xFF" + strings.Repeat("B", 1024), + wantCT: "image/jpeg", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + input := make([]byte, len(streamFullRequestStdin)) + copy(input, streamFullRequestStdin) + rc := nopWriteCloser{bytes.NewBuffer(input)} + done := make(chan bool) + var resp *response + c := newChild(rc, http.HandlerFunc(func( + w http.ResponseWriter, + r *http.Request, + ) { + io.WriteString(w, tt.body) + resp = w.(*response) + done <- true + })) + defer c.cleanUp() + go c.serve() + <-done + if got := resp.Header().Get("Content-Type"); got != tt.wantCT { + t.Errorf("got a Content-Type of %q; expected it to start with %q", got, tt.wantCT) + } + }) + } +} diff --git a/libgo/go/net/mail/message.go b/libgo/go/net/mail/message.go index 6833cfa..09fb794 100644 --- a/libgo/go/net/mail/message.go +++ b/libgo/go/net/mail/message.go @@ -279,9 +279,6 @@ func (p *addrParser) parseAddressList() ([]*Address, error) { if p.consume(',') { continue } - if p.empty() { - break - } addrs, err := p.parseAddress(true) if err != nil { @@ -295,9 +292,17 @@ func (p *addrParser) parseAddressList() ([]*Address, error) { if p.empty() { break } - if !p.consume(',') { + if p.peek() != ',' { return nil, errors.New("mail: expected comma") } + + // Skip empty entries for obs-addr-list. + for p.consume(',') { + p.skipSpace() + } + if p.empty() { + break + } } return list, nil } diff --git a/libgo/go/net/mail/message_test.go b/libgo/go/net/mail/message_test.go index 75db767..67e3643 100644 --- a/libgo/go/net/mail/message_test.go +++ b/libgo/go/net/mail/message_test.go @@ -446,6 +446,19 @@ func TestAddressParsing(t *testing.T) { }, }, { + ` , joe@where.test,,John ,,`, + []*Address{ + { + Name: "", + Address: "joe@where.test", + }, + { + Name: "John", + Address: "jdoe@one.test", + }, + }, + }, + { `Group1: ;, Group 2: addr2@example.com;, John `, []*Address{ { @@ -1067,3 +1080,22 @@ func TestAddressFormattingAndParsing(t *testing.T) { } } } + +func TestEmptyAddress(t *testing.T) { + parsed, err := ParseAddress("") + if parsed != nil || err == nil { + t.Errorf(`ParseAddress("") = %v, %v, want nil, error`, parsed, err) + } + list, err := ParseAddressList("") + if len(list) > 0 || err == nil { + t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err) + } + list, err = ParseAddressList(",") + if len(list) > 0 || err == nil { + t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err) + } + list, err = ParseAddressList("a@b c@d") + if len(list) > 0 || err == nil { + t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err) + } +} diff --git a/libgo/go/runtime/checkptr_test.go b/libgo/go/runtime/checkptr_test.go index 76aa2cd..bd2d00f 100644 --- a/libgo/go/runtime/checkptr_test.go +++ b/libgo/go/runtime/checkptr_test.go @@ -31,6 +31,7 @@ func TestCheckPtr(t *testing.T) { {"CheckPtrAlignmentPtr", "fatal error: checkptr: misaligned pointer conversion\n"}, {"CheckPtrAlignmentNoPtr", ""}, {"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"}, + {"CheckPtrArithmetic2", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"}, {"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"}, {"CheckPtrSmall", "fatal error: checkptr: pointer arithmetic computed bad pointer value\n"}, } diff --git a/libgo/go/runtime/lockrank_off.go b/libgo/go/runtime/lockrank_off.go index 425ca8d..32378a9 100644 --- a/libgo/go/runtime/lockrank_off.go +++ b/libgo/go/runtime/lockrank_off.go @@ -18,19 +18,29 @@ func getLockRank(l *mutex) lockRank { return 0 } +// The following functions may be called in nosplit context. +// Nosplit is not strictly required for lockWithRank, unlockWithRank +// and lockWithRankMayAcquire, but these nosplit annotations must +// be kept consistent with the equivalent functions in lockrank_on.go. + +//go:nosplit func lockWithRank(l *mutex, rank lockRank) { lock2(l) } +//go:nosplit func acquireLockRank(rank lockRank) { } +//go:nosplit func unlockWithRank(l *mutex) { unlock2(l) } +//go:nosplit func releaseLockRank(rank lockRank) { } +//go:nosplit func lockWithRankMayAcquire(l *mutex, rank lockRank) { } diff --git a/libgo/go/runtime/testdata/testprog/checkptr.go b/libgo/go/runtime/testdata/testprog/checkptr.go index 45e6fb1..e0a2794 100644 --- a/libgo/go/runtime/testdata/testprog/checkptr.go +++ b/libgo/go/runtime/testdata/testprog/checkptr.go @@ -10,6 +10,7 @@ func init() { register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr) register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr) register("CheckPtrArithmetic", CheckPtrArithmetic) + register("CheckPtrArithmetic2", CheckPtrArithmetic2) register("CheckPtrSize", CheckPtrSize) register("CheckPtrSmall", CheckPtrSmall) } @@ -32,6 +33,13 @@ func CheckPtrArithmetic() { sink2 = (*int)(unsafe.Pointer(i)) } +func CheckPtrArithmetic2() { + var x [2]int64 + p := unsafe.Pointer(&x[1]) + var one uintptr = 1 + sink2 = unsafe.Pointer(uintptr(p) & ^one) +} + func CheckPtrSize() { p := new(int64) sink2 = p diff --git a/libgo/go/sync/map.go b/libgo/go/sync/map.go index a61e2eb..9ad2535 100644 --- a/libgo/go/sync/map.go +++ b/libgo/go/sync/map.go @@ -274,6 +274,7 @@ func (m *Map) LoadAndDelete(key interface{}) (value interface{}, loaded bool) { e, ok = read.m[key] if !ok && read.amended { e, ok = m.dirty[key] + delete(m.dirty, key) // Regardless of whether the entry was present, record a miss: this key // will take the slow path until the dirty map is promoted to the read // map. diff --git a/libgo/go/sync/map_test.go b/libgo/go/sync/map_test.go index 4ae989a..7f163ca 100644 --- a/libgo/go/sync/map_test.go +++ b/libgo/go/sync/map_test.go @@ -9,6 +9,7 @@ import ( "reflect" "runtime" "sync" + "sync/atomic" "testing" "testing/quick" ) @@ -171,3 +172,26 @@ func TestConcurrentRange(t *testing.T) { } } } + +func TestIssue40999(t *testing.T) { + var m sync.Map + + // Since the miss-counting in missLocked (via Delete) + // compares the miss count with len(m.dirty), + // add an initial entry to bias len(m.dirty) above the miss count. + m.Store(nil, struct{}{}) + + var finalized uint32 + + // Set finalizers that count for collected keys. A non-zero count + // indicates that keys have not been leaked. + for atomic.LoadUint32(&finalized) == 0 { + p := new(int) + runtime.SetFinalizer(p, func(*int) { + atomic.AddUint32(&finalized, 1) + }) + m.Store(p, struct{}{}) + m.Delete(p) + runtime.GC() + } +} diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go index dee77f7..fe6929d 100644 --- a/libgo/go/testing/testing.go +++ b/libgo/go/testing/testing.go @@ -357,10 +357,19 @@ func (p *testPrinter) Fprint(w io.Writer, testName, out string) { defer p.lastNameMu.Unlock() if !p.chatty || - strings.HasPrefix(out, "--- PASS") || - strings.HasPrefix(out, "--- FAIL") || - strings.HasPrefix(out, "=== CONT") || - strings.HasPrefix(out, "=== RUN") { + strings.HasPrefix(out, "--- PASS: ") || + strings.HasPrefix(out, "--- FAIL: ") || + strings.HasPrefix(out, "--- SKIP: ") || + strings.HasPrefix(out, "=== RUN ") || + strings.HasPrefix(out, "=== CONT ") || + strings.HasPrefix(out, "=== PAUSE ") { + // If we're buffering test output (!p.chatty), we don't really care which + // test is emitting which line so long as they are serialized. + // + // If the message already implies an association with a specific new test, + // we don't need to check what the old test name was or log an extra CONT + // line for it. (We're updating it anyway, and the current message already + // includes the test name.) p.lastName = testName fmt.Fprint(w, out) return @@ -887,11 +896,15 @@ func (c *common) Cleanup(f func()) { c.cleanup = func() { if oldCleanup != nil { defer func() { + c.mu.Lock() c.cleanupPc = oldCleanupPc + c.mu.Unlock() oldCleanup() }() } + c.mu.Lock() c.cleanupName = callerName(0) + c.mu.Unlock() f() } var pc [maxStackLen]uintptr @@ -1012,7 +1025,13 @@ func (t *T) Parallel() { for ; root.parent != nil; root = root.parent { } root.mu.Lock() - fmt.Fprintf(root.w, "=== PAUSE %s\n", t.name) + // Unfortunately, even though PAUSE indicates that the named test is *no + // longer* running, cmd/test2json interprets it as changing the active test + // for the purpose of log parsing. We could fix cmd/test2json, but that + // won't fix existing deployments of third-party tools that already shell + // out to older builds of cmd/test2json — so merely fixing cmd/test2json + // isn't enough for now. + printer.Fprint(root.w, t.name, fmt.Sprintf("=== PAUSE %s\n", t.name)) root.mu.Unlock() } diff --git a/libgo/merge.sh b/libgo/merge.sh index bddb132..f8de950 100755 --- a/libgo/merge.sh +++ b/libgo/merge.sh @@ -128,7 +128,7 @@ echo ${rev} > VERSION (cd ${NEWDIR}/src && find . -name '*.go' -print) | while read f; do skip=false case "$f" in - ./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/testjson/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/testj2on/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/* | ./cmd/vendor/golang.org/x/mod/* | ./cmd/vendor/golang.org/x/xerrors/* | ./cmd/vendor/golang.org/x/crypto/ed25519) + ./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/test2json/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/test2json/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/* | ./cmd/vendor/golang.org/x/mod/* | ./cmd/vendor/golang.org/x/xerrors/* | ./cmd/vendor/golang.org/x/crypto/ed25519) ;; ./cmd/*) skip=true @@ -150,7 +150,7 @@ done (cd ${NEWDIR}/src && find . -name testdata -print) | while read d; do skip=false case "$d" in - ./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/testjson/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/diff/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/testj2on/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/*) + ./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/test2json/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/diff/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/test2json/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/*) ;; ./cmd/*) skip=true -- cgit v1.1 From 1b8a23fc97de65f3188d0cdd5bfb56060defa84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Wed, 23 Sep 2020 16:08:21 +0200 Subject: runtime: remove __go_ptrace on AIX AIX ptrace syscalls doesn't have the same semantic than the glibc one. The syscall package is already handling it correctly so disable the new __go_ptrace C function for AIX. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/256777 --- libgo/runtime/go-varargs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/runtime/go-varargs.c b/libgo/runtime/go-varargs.c index f9270a9..9cb4a7e 100644 --- a/libgo/runtime/go-varargs.c +++ b/libgo/runtime/go-varargs.c @@ -114,7 +114,9 @@ __go_syscall6(uintptr_t flag, uintptr_t a1, uintptr_t a2, uintptr_t a3, #endif -#ifdef HAVE_SYS_PTRACE_H +// AIX ptrace is really different from Linux ptrace. Let syscall +// package handles it. +#if defined(HAVE_SYS_PTRACE_H) && !defined(_AIX) // Despite documented appearances, this is actually implemented as // a variadic function within glibc. -- cgit v1.1 From 9042b6605c259e55378a1f0eefc24b43363bb55b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 26 Sep 2020 12:11:51 -0700 Subject: net: add hurd build tag Patch from Svante Signell. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/257857 --- libgo/go/net/fd_posix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/go/net/fd_posix.go b/libgo/go/net/fd_posix.go index 53abd15..b2f99bc 100644 --- a/libgo/go/net/fd_posix.go +++ b/libgo/go/net/fd_posix.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 aix darwin dragonfly freebsd linux netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris windows package net -- cgit v1.1 From 2c5499b57cf4a68ebc8decce90d3eb1e281c31a9 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 28 Aug 2020 16:05:56 +0100 Subject: libgo: add 32-bit RISC-V (RV32) support Add support for the 32-bit RISC-V (RV32) ISA matching the 64-bit RISC-V (RV64) port except for async preemption added as a stub only. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/251179 --- libgo/configure | 17 ++++++++- libgo/configure.ac | 10 ++++- libgo/go/cmd/cgo/main.go | 2 + .../go/testdata/script/link_syso_issue33139.txt | 3 +- libgo/go/cmd/internal/sys/arch.go | 11 ++++++ libgo/go/debug/elf/file.go | 43 ++++++++++++++++++++++ libgo/go/go/types/sizes.go | 4 +- libgo/go/golang.org/x/sys/cpu/cpu_riscv.go | 7 ++++ .../x/tools/go/analysis/passes/asmdecl/asmdecl.go | 2 + libgo/go/internal/bytealg/indexbyte_generic.go | 2 +- libgo/go/internal/bytealg/indexbyte_native.go | 2 +- .../internal/syscall/unix/sysnum_linux_generic.go | 2 +- libgo/go/runtime/gcinfo_test.go | 2 +- libgo/go/runtime/hash32.go | 2 +- libgo/go/runtime/lfstack_32bit.go | 2 +- libgo/go/runtime/mkpreempt.go | 6 +++ libgo/go/runtime/mpagealloc_32bit.go | 2 +- libgo/go/syscall/endian_little.go | 2 +- libgo/match.sh | 4 +- libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go | 2 +- libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go | 2 +- libgo/testsuite/gotest | 4 +- 22 files changed, 113 insertions(+), 20 deletions(-) create mode 100644 libgo/go/golang.org/x/sys/cpu/cpu_riscv.go (limited to 'libgo') diff --git a/libgo/configure b/libgo/configure index 7be9571..641d060 100755 --- a/libgo/configure +++ b/libgo/configure @@ -14226,8 +14226,21 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; - riscv64-*-*) - GOARCH=riscv64 + riscv*-*-*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if __riscv_xlen == 64 +#error 64-bit +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + GOARCH=riscv +else + GOARCH=riscv64 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; s390*-*-*) cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/libgo/configure.ac b/libgo/configure.ac index abc58b8..f15f8d8 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -342,8 +342,14 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ [GOARCH=ppc64le], [GOARCH=ppc64])]) ;; - riscv64-*-*) - GOARCH=riscv64 + riscv*-*-*) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +#if __riscv_xlen == 64 +#error 64-bit +#endif +])], +[GOARCH=riscv], +[GOARCH=riscv64]) ;; s390*-*-*) AC_COMPILE_IFELSE([AC_LANG_SOURCE([ diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go index 80f3568..6de6d69 100644 --- a/libgo/go/cmd/cgo/main.go +++ b/libgo/go/cmd/cgo/main.go @@ -184,6 +184,7 @@ var ptrSizeMap = map[string]int64{ "ppc": 4, "ppc64": 8, "ppc64le": 8, + "riscv": 4, "riscv64": 8, "s390": 4, "s390x": 8, @@ -210,6 +211,7 @@ var intSizeMap = map[string]int64{ "ppc": 4, "ppc64": 8, "ppc64le": 8, + "riscv": 4, "riscv64": 8, "s390": 4, "s390x": 8, diff --git a/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt index 46b0ef4..3030ee9 100644 --- a/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt +++ b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt @@ -8,8 +8,9 @@ # See: https://github.com/golang/go/issues/8912 [linux] [ppc64] skip -# External linking is not supported on linux/riscv64. +# External linking is not supported on linux/riscv, linux/riscv64. # See: https://github.com/golang/go/issues/36739 +[linux] [riscv] skip [linux] [riscv64] skip cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c diff --git a/libgo/go/cmd/internal/sys/arch.go b/libgo/go/cmd/internal/sys/arch.go index e868736..60a3b3c 100644 --- a/libgo/go/cmd/internal/sys/arch.go +++ b/libgo/go/cmd/internal/sys/arch.go @@ -19,6 +19,7 @@ const ( MIPS MIPS64 PPC64 + RISCV RISCV64 S390X Wasm @@ -143,6 +144,15 @@ var ArchPPC64LE = &Arch{ MinLC: 4, } +var ArchRISCV = &Arch{ + Name: "riscv", + Family: RISCV, + ByteOrder: binary.LittleEndian, + PtrSize: 4, + RegSize: 4, + MinLC: 4, +} + var ArchRISCV64 = &Arch{ Name: "riscv64", Family: RISCV64, @@ -181,6 +191,7 @@ var Archs = [...]*Arch{ ArchMIPS64LE, ArchPPC64, ArchPPC64LE, + ArchRISCV, ArchRISCV64, ArchS390X, ArchWasm, diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go index b9a8b1e..48178d4 100644 --- a/libgo/go/debug/elf/file.go +++ b/libgo/go/debug/elf/file.go @@ -617,6 +617,8 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error { return f.applyRelocationsMIPS(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_MIPS: return f.applyRelocationsMIPS64(dst, rels) + case f.Class == ELFCLASS32 && f.Machine == EM_RISCV: + return f.applyRelocationsRISCV(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_RISCV: return f.applyRelocationsRISCV64(dst, rels) case f.Class == ELFCLASS64 && f.Machine == EM_S390: @@ -1008,6 +1010,47 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error { return nil } +func (f *File) applyRelocationsRISCV(dst []byte, rels []byte) error { + // 12 is the size of Rela32. + if len(rels)%12 != 0 { + return errors.New("length of relocation section is not a multiple of 12") + } + + symbols, _, err := f.getSymbols(SHT_SYMTAB) + if err != nil { + return err + } + + b := bytes.NewReader(rels) + var rela Rela32 + + for b.Len() > 0 { + binary.Read(b, f.ByteOrder, &rela) + symNo := rela.Info >> 8 + t := R_RISCV(rela.Info & 0xff) + + if symNo == 0 || symNo > uint32(len(symbols)) { + continue + } + sym := &symbols[symNo-1] + needed, val := relocSymbolTargetOK(sym) + if !needed { + continue + } + + switch t { + case R_RISCV_32: + if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 { + continue + } + val32 := uint32(val) + uint32(rela.Addend) + f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) + } + } + + return nil +} + func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { diff --git a/libgo/go/go/types/sizes.go b/libgo/go/go/types/sizes.go index 6ab6157..4787b24 100644 --- a/libgo/go/go/types/sizes.go +++ b/libgo/go/go/types/sizes.go @@ -167,6 +167,7 @@ var gcArchSizes = map[string]*StdSizes{ "mips64le": {8, 8}, "ppc64": {8, 8}, "ppc64le": {8, 8}, + "riscv": {4, 4}, "riscv64": {8, 8}, "s390x": {8, 8}, "sparc64": {8, 8}, @@ -180,7 +181,8 @@ var gcArchSizes = map[string]*StdSizes{ // // Supported architectures for compiler "gc": // "386", "arm", "arm64", "amd64", "amd64p32", "mips", "mipsle", -// "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sparc64", "wasm". +// "mips64", "mips64le", "ppc64", "ppc64le", "riscv", "riscv64", +// "s390x", "sparc64", "wasm". func SizesFor(compiler, arch string) Sizes { var m map[string]*StdSizes switch compiler { diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_riscv.go b/libgo/go/golang.org/x/sys/cpu/cpu_riscv.go new file mode 100644 index 0000000..891cb98 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_riscv.go @@ -0,0 +1,7 @@ +// 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 riscv + +package cpu diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go b/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go index e6bfe71..0f52150 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go @@ -87,6 +87,7 @@ var ( asmArchMips64LE = asmArch{name: "mips64le", bigEndian: false, stack: "R29", lr: true} asmArchPpc64 = asmArch{name: "ppc64", bigEndian: true, stack: "R1", lr: true} asmArchPpc64LE = asmArch{name: "ppc64le", bigEndian: false, stack: "R1", lr: true} + asmArchRISCV = asmArch{name: "riscv", bigEndian: false, stack: "SP", lr: true} asmArchRISCV64 = asmArch{name: "riscv64", bigEndian: false, stack: "SP", lr: true} asmArchS390X = asmArch{name: "s390x", bigEndian: true, stack: "R15", lr: true} asmArchWasm = asmArch{name: "wasm", bigEndian: false, stack: "SP", lr: false} @@ -102,6 +103,7 @@ var ( &asmArchMips64LE, &asmArchPpc64, &asmArchPpc64LE, + &asmArchRISCV, &asmArchRISCV64, &asmArchS390X, &asmArchWasm, diff --git a/libgo/go/internal/bytealg/indexbyte_generic.go b/libgo/go/internal/bytealg/indexbyte_generic.go index a863d81..46325dd 100644 --- a/libgo/go/internal/bytealg/indexbyte_generic.go +++ b/libgo/go/internal/bytealg/indexbyte_generic.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build ignore_for_gccgo -// +build !386,!amd64,!s390x,!arm,!arm64,!ppc64,!ppc64le,!mips,!mipsle,!mips64,!mips64le,!riscv64,!wasm +// +build !386,!amd64,!s390x,!arm,!arm64,!ppc64,!ppc64le,!mips,!mipsle,!mips64,!mips64le,!riscv,!riscv64,!wasm package bytealg diff --git a/libgo/go/internal/bytealg/indexbyte_native.go b/libgo/go/internal/bytealg/indexbyte_native.go index 20da788..c427e66 100644 --- a/libgo/go/internal/bytealg/indexbyte_native.go +++ b/libgo/go/internal/bytealg/indexbyte_native.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 386 amd64 s390x arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le riscv64 wasm +// -build 386 amd64 s390x arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le riscv riscv64 wasm package bytealg diff --git a/libgo/go/internal/syscall/unix/sysnum_linux_generic.go b/libgo/go/internal/syscall/unix/sysnum_linux_generic.go index 3e00703..3d34fdb 100644 --- a/libgo/go/internal/syscall/unix/sysnum_linux_generic.go +++ b/libgo/go/internal/syscall/unix/sysnum_linux_generic.go @@ -9,7 +9,7 @@ package unix // This file is named "generic" because at a certain point Linux started // standardizing on system call numbers across architectures. So far this -// means only arm64, nios2 and riscv use the standard numbers. +// means only arm64, nios2, riscv and riscv64 use the standard numbers. const ( getrandomTrap uintptr = 278 diff --git a/libgo/go/runtime/gcinfo_test.go b/libgo/go/runtime/gcinfo_test.go index ddbe5dd..c26f411 100644 --- a/libgo/go/runtime/gcinfo_test.go +++ b/libgo/go/runtime/gcinfo_test.go @@ -157,7 +157,7 @@ type BigStruct struct { func infoBigStruct() []byte { switch runtime.GOARCH { - case "386", "arm", "mips", "mipsle": + case "386", "arm", "mips", "mipsle", "riscv": return []byte{ typePointer, // q *int typeScalar, typeScalar, typeScalar, typeScalar, typeScalar, // w byte; e [17]byte diff --git a/libgo/go/runtime/hash32.go b/libgo/go/runtime/hash32.go index fba6bc3..89efc1c 100644 --- a/libgo/go/runtime/hash32.go +++ b/libgo/go/runtime/hash32.go @@ -6,7 +6,7 @@ // xxhash: https://code.google.com/p/xxhash/ // cityhash: https://code.google.com/p/cityhash/ -// +build 386 arm armbe m68k mips mipsle nios2 ppc s390 sh shbe sparc +// +build 386 arm armbe m68k mips mipsle nios2 ppc riscv s390 sh shbe sparc package runtime diff --git a/libgo/go/runtime/lfstack_32bit.go b/libgo/go/runtime/lfstack_32bit.go index 6da037e..b3194dc 100644 --- a/libgo/go/runtime/lfstack_32bit.go +++ b/libgo/go/runtime/lfstack_32bit.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 386 amd64p32 arm armbe m68k mips mipsle mips64p32 mips64p32le nios2 ppc s390 sh shbe sparc +// +build 386 amd64p32 arm armbe m68k mips mipsle mips64p32 mips64p32le nios2 ppc riscv s390 sh shbe sparc package runtime diff --git a/libgo/go/runtime/mkpreempt.go b/libgo/go/runtime/mkpreempt.go index 1fe7766..268941d 100644 --- a/libgo/go/runtime/mkpreempt.go +++ b/libgo/go/runtime/mkpreempt.go @@ -83,6 +83,7 @@ var arches = map[string]func(){ "mips64x": func() { genMIPS(true) }, "mipsx": func() { genMIPS(false) }, "ppc64x": genPPC64, + "riscv": genRISCV, "riscv64": genRISCV64, "s390x": genS390X, "wasm": genWasm, @@ -501,6 +502,11 @@ func genPPC64() { p("JMP (CTR)") } +func genRISCV() { + p("// No async preemption on riscv - see issue 36711") + p("UNDEF") +} + func genRISCV64() { // X0 (zero), X1 (LR), X2 (SP), X4 (g), X31 (TMP) are special. var l = layout{sp: "X2", stack: 8} diff --git a/libgo/go/runtime/mpagealloc_32bit.go b/libgo/go/runtime/mpagealloc_32bit.go index d18970c..249b5fe 100644 --- a/libgo/go/runtime/mpagealloc_32bit.go +++ b/libgo/go/runtime/mpagealloc_32bit.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 386 arm mips mipsle wasm darwin,arm64 amd64p32 armbe m68k mips64p32 mips64p32le nios2 ppc s390 sh shbe sparc +// +build 386 arm mips mipsle wasm darwin,arm64 amd64p32 armbe m68k mips64p32 mips64p32le nios2 ppc riscv s390 sh shbe sparc // wasm is a treated as a 32-bit architecture for the purposes of the page // allocator, even though it has 64-bit pointers. This is because any wasm diff --git a/libgo/go/syscall/endian_little.go b/libgo/go/syscall/endian_little.go index 0cd2d75..22cac17 100644 --- a/libgo/go/syscall/endian_little.go +++ b/libgo/go/syscall/endian_little.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 386 alpha amd64 amd64p32 arm arm64 ia64 mips64le mipsle mips64p32le nios2 ppc64le riscv64 sh wasm +// +build 386 alpha amd64 amd64p32 arm arm64 ia64 mips64le mipsle mips64p32le nios2 ppc64le riscv riscv64 sh wasm package syscall diff --git a/libgo/match.sh b/libgo/match.sh index cd35942..6f7b368 100755 --- a/libgo/match.sh +++ b/libgo/match.sh @@ -116,7 +116,7 @@ for f in $gofiles; do aix | android | darwin | dragonfly | freebsd | illumos | hurd | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag1=nonmatchingtag ;; - 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) + 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) tag1=nonmatchingtag ;; esac @@ -128,7 +128,7 @@ for f in $gofiles; do aix | android | darwin | dragonfly | freebsd | hurd | illumos | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag2=nonmatchingtag ;; - 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) + 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) tag2=nonmatchingtag ;; esac diff --git a/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go b/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go index d343aa5..3b53e1c 100644 --- a/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go +++ b/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.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 linux,!arm64,!riscv64 netbsd openbsd +// +build darwin dragonfly freebsd linux,!arm64,!riscv,!riscv64 netbsd openbsd package main diff --git a/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go b/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go index 459f0dc..79a3773 100644 --- a/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go +++ b/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.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 linux,arm64 linux,riscv64 +// +build linux,arm64 linux,riscv,riscv64 package main diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest index eadafa1..5bb27ec 100755 --- a/libgo/testsuite/gotest +++ b/libgo/testsuite/gotest @@ -308,7 +308,7 @@ x) aix | android | darwin | dragonfly | freebsd | hurd | illumos | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag1=nonmatchingtag ;; - 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) + 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) tag1=nonmatchingtag ;; esac @@ -320,7 +320,7 @@ x) aix | android | darwin | dragonfly | freebsd | hurd | illumos | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag2=nonmatchingtag ;; - 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) + 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) tag2=nonmatchingtag ;; esac -- cgit v1.1 From 3e52eaab8c57ad06bcd553f140923a34e5749991 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 1 Oct 2020 15:11:22 -0700 Subject: compiler: set varargs correctly for type of method expression Fixes golang/go#41737 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/258977 --- libgo/go/reflect/all_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index ee37359..68efab6 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -2396,8 +2396,14 @@ func TestVariadicMethodValue(t *testing.T) { points := []Point{{20, 21}, {22, 23}, {24, 25}} want := int64(p.TotalDist(points[0], points[1], points[2])) + // Variadic method of type. + tfunc := TypeOf((func(Point, ...Point) int)(nil)) + if tt := TypeOf(p).Method(4).Type; tt != tfunc { + t.Errorf("Variadic Method Type from TypeOf is %s; want %s", tt, tfunc) + } + // Curried method of value. - tfunc := TypeOf((func(...Point) int)(nil)) + tfunc = TypeOf((func(...Point) int)(nil)) v := ValueOf(p).Method(4) if tt := v.Type(); tt != tfunc { t.Errorf("Variadic Method Type is %s; want %s", tt, tfunc) -- cgit v1.1 From 89d3af5ef7e313efd7a5e88a4c629b4704cfe976 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Wed, 7 Oct 2020 01:14:49 -0400 Subject: libgo: handle go1.10+ correctly in match.sh match.sh was not correctly handling build constraints for Go versions that have a two-digit suffix, like "go1.10". The same issue will arise with Go 1.100, but that is a long ways off. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/260077 --- libgo/match.sh | 8 ++++---- libgo/testsuite/gotest | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'libgo') diff --git a/libgo/match.sh b/libgo/match.sh index 6f7b368..04db8d2 100755 --- a/libgo/match.sh +++ b/libgo/match.sh @@ -151,18 +151,18 @@ for f in $gofiles; do fi match=false ;; - $goos | $goarch | $cgotag | $cmdlinetag | "gccgo" | go1.[0-9]) + $goos | $goarch | $cgotag | $cmdlinetag | "gccgo" | go1.[0-9] | go1.[0-9][0-9]) match=true ;; - "!"$goos | "!"$goarch | "!"$cgotag | "!"$cmdlinetag | "!gccgo" | "!"go1.[0-9]) + "!"$goos | "!"$goarch | "!"$cgotag | "!"$cmdlinetag | "!gccgo" | "!"go1.[0-9] | "!"go1.[0-9][0-9]) ;; *,*) cmatch=true for ctag in `echo $tag | sed -e 's/,/ /g'`; do case $ctag in - $goos | $goarch | $cgotag | $cmdlinetag | "gccgo" | go1.[0-9]) + $goos | $goarch | $cgotag | $cmdlinetag | "gccgo" | go1.[0-9] | go1.[0-9][0-9]) ;; - "!"$goos | "!"$goarch | "!"$cgotag | "!"$cmdlinetag | "!gccgo" | "!"go1.[0-9]) + "!"$goos | "!"$goarch | "!"$cgotag | "!"$cmdlinetag | "!gccgo" | "!"go1.[0-9] | "!"go1.[0-9][0-9]) cmatch=false ;; "!"*) diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest index 5bb27ec..0fd6419 100755 --- a/libgo/testsuite/gotest +++ b/libgo/testsuite/gotest @@ -342,18 +342,18 @@ x) fi match=false ;; - $goos | $goarch | cgo | gccgo | go1.[0-9]) + $goos | $goarch | cgo | gccgo | go1.[0-9] | go1.[0-9][0-9]) match=true ;; - "!"$goos | "!"$goarch | "!cgo" | "!gccgo" | "!"go1.[0-9]) + "!"$goos | "!"$goarch | "!cgo" | "!gccgo" | "!"go1.[0-9] | "!"go1.[0-9][0-9]) ;; *,*) cmatch=true for ctag in `echo $tag | sed -e 's/,/ /g'`; do case $ctag in - $goos | $goarch | cgo | gccgo | go1.[0-9]) + $goos | $goarch | cgo | gccgo | go1.[0-9] | go1.[0-9][0-9]) ;; - "!"$goos | "!"$goarch | "!cgo" | "!gccgo" | "!"go1.[0-9]) + "!"$goos | "!"$goarch | "!cgo" | "!gccgo" | "!"go1.[0-9] | "!"go1.[0-9][0-9]) cmatch=false ;; "!"*) -- cgit v1.1 From 45376dc0f426c0fc39c5ee77937c928c27fab77a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Thu, 24 Sep 2020 13:40:40 +0200 Subject: libgo/configure: remove -fno-section-anchors for AIX This option is no longer needed. There is no crash without it since at least gcc-9. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/260157 --- libgo/configure | 8 ++------ libgo/configure.ac | 4 ---- 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'libgo') diff --git a/libgo/configure b/libgo/configure index 641d060..792ac6f 100755 --- a/libgo/configure +++ b/libgo/configure @@ -4711,10 +4711,6 @@ fi case ${host} in *-*-aix*) - # static hash tables crashes on AIX when libgo is built with O2 - CFLAGS="$CFLAGS -fno-section-anchors" - GOCFLAGS="$GOCFLAGS -fno-section-anchors" - # Check default architecture for FAT library creation if test -z "`$CC -x c -E /dev/null -g3 -o - | grep 64BIT`" ; then AIX_EXTRA_ARCH='64' @@ -11501,7 +11497,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11504 "configure" +#line 11500 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11607,7 +11603,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11610 "configure" +#line 11606 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libgo/configure.ac b/libgo/configure.ac index f15f8d8..9a10d33 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -33,10 +33,6 @@ AC_SUBST(CFLAGS) case ${host} in *-*-aix*) - # static hash tables crashes on AIX when libgo is built with O2 - CFLAGS="$CFLAGS -fno-section-anchors" - GOCFLAGS="$GOCFLAGS -fno-section-anchors" - # Check default architecture for FAT library creation if test -z "`$CC -x c -E /dev/null -g3 -o - | grep 64BIT`" ; then AIX_EXTRA_ARCH='64' -- cgit v1.1 From 72b38338228b3e90879828c0bb059603f683d98b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Wed, 7 Oct 2020 15:47:45 +0200 Subject: reflect: ensure uniqueness of type descriptors on AIX. On AIX, duplication of type descriptors can occur if one is declared in the libgo and one in the Go program being compiled. The AIX linker isn't able to merge them together as Linux one does. One solution is to always load libgo first but that needs a huge mechanism in gcc core. Thus, this patch ensures that the duplication isn't visible for the end user. In reflect and internal/reflectlite, the comparison of rtypes is made on their name and not only on their addresses. In reflect, toType() function is using a canonicalization map to force rtypes having the same rtype.String() to return the same Type. This can't be made in internal/reflectlite as it needs sync package. But, for now, it doesn't matter as internal/reflectlite is not widely used. Fixes golang/go#39276 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/260158 --- libgo/Makefile.am | 6 ++ libgo/Makefile.in | 4 ++ libgo/go/internal/reflectlite/eqtype.go | 12 ++++ libgo/go/internal/reflectlite/eqtype_aix_gccgo.go | 26 ++++++++ libgo/go/internal/reflectlite/type.go | 8 +-- libgo/go/reflect/eqtype.go | 24 ++++++++ libgo/go/reflect/eqtype_aix_gccgo.go | 74 +++++++++++++++++++++++ libgo/go/reflect/type.go | 40 +++++------- libgo/go/reflect/value.go | 2 +- 9 files changed, 167 insertions(+), 29 deletions(-) create mode 100644 libgo/go/internal/reflectlite/eqtype.go create mode 100644 libgo/go/internal/reflectlite/eqtype_aix_gccgo.go create mode 100644 libgo/go/reflect/eqtype.go create mode 100644 libgo/go/reflect/eqtype_aix_gccgo.go (limited to 'libgo') diff --git a/libgo/Makefile.am b/libgo/Makefile.am index e3f08a2..76cdc8ef 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -973,6 +973,12 @@ endif # Also use -fno-inline to get better results from the memory profiler. runtime_pprof_check_GOCFLAGS = -static-libgo -fno-inline +if LIBGO_IS_AIX +# reflect tests must be done with -static-libgo. Otherwize, +# there will be a duplication of the canonicalization map. +reflect_check_GOCFLAGS = -static-libgo -Wl,-bbigtoc +endif + if HAVE_STATIC_LINK # Use -static for the syscall tests if possible, because otherwise when # running as root the re-execs ignore LD_LIBRARY_PATH. diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 18b1a06..59a7083 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -1114,6 +1114,10 @@ runtime_internal_sys_lo_check_GOCFLAGS = -fgo-compiling-runtime # Also use -fno-inline to get better results from the memory profiler. runtime_pprof_check_GOCFLAGS = -static-libgo -fno-inline +# reflect tests must be done with -static-libgo. Otherwize, +# there will be a duplication of the canonicalization map. +@LIBGO_IS_AIX_TRUE@reflect_check_GOCFLAGS = -static-libgo -Wl,-bbigtoc + # Use -static for the syscall tests if possible, because otherwise when # running as root the re-execs ignore LD_LIBRARY_PATH. @HAVE_STATIC_LINK_TRUE@syscall_check_GOCFLAGS = -static diff --git a/libgo/go/internal/reflectlite/eqtype.go b/libgo/go/internal/reflectlite/eqtype.go new file mode 100644 index 0000000..a03cf1c --- /dev/null +++ b/libgo/go/internal/reflectlite/eqtype.go @@ -0,0 +1,12 @@ +// 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 !aix !gccgo + +package reflectlite + +// rtypeEqual returns true if both types are identical. +func rtypeEqual(t1, t2 *rtype) bool { + return t1 == t2 +} diff --git a/libgo/go/internal/reflectlite/eqtype_aix_gccgo.go b/libgo/go/internal/reflectlite/eqtype_aix_gccgo.go new file mode 100644 index 0000000..38b507f --- /dev/null +++ b/libgo/go/internal/reflectlite/eqtype_aix_gccgo.go @@ -0,0 +1,26 @@ +// 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 aix,gccgo + +// AIX linker isn't able to merge identical type descriptors coming from +// different objects. Thus, two rtypes might have two different pointers +// even if they are the same. Thus, instead of pointer equality, string +// field is checked. + +package reflectlite + +// rtypeEqual returns true if both types are identical. +func rtypeEqual(t1, t2 *rtype) bool { + switch { + case t1 == t2: + return true + case t1 == nil || t2 == nil: + return false + case t1.kind != t2.kind || t1.hash != t2.hash: + return false + default: + return t1.String() == t2.String() + } +} diff --git a/libgo/go/internal/reflectlite/type.go b/libgo/go/internal/reflectlite/type.go index e700a55..1609a06 100644 --- a/libgo/go/internal/reflectlite/type.go +++ b/libgo/go/internal/reflectlite/type.go @@ -539,7 +539,7 @@ func implements(T, V *rtype) bool { for j := 0; j < len(v.methods); j++ { tm := &t.methods[i] vm := &v.methods[j] - if *vm.name == *tm.name && (vm.pkgPath == tm.pkgPath || (vm.pkgPath != nil && tm.pkgPath != nil && *vm.pkgPath == *tm.pkgPath)) && toType(vm.typ).common() == toType(tm.typ).common() { + if *vm.name == *tm.name && (vm.pkgPath == tm.pkgPath || (vm.pkgPath != nil && tm.pkgPath != nil && *vm.pkgPath == *tm.pkgPath)) && rtypeEqual(toType(vm.typ).common(), toType(tm.typ).common()) { if i++; i >= len(t.methods) { return true } @@ -556,7 +556,7 @@ func implements(T, V *rtype) bool { for j := 0; j < len(v.methods); j++ { tm := &t.methods[i] vm := &v.methods[j] - if *vm.name == *tm.name && (vm.pkgPath == tm.pkgPath || (vm.pkgPath != nil && tm.pkgPath != nil && *vm.pkgPath == *tm.pkgPath)) && toType(vm.mtyp).common() == toType(tm.typ).common() { + if *vm.name == *tm.name && (vm.pkgPath == tm.pkgPath || (vm.pkgPath != nil && tm.pkgPath != nil && *vm.pkgPath == *tm.pkgPath)) && rtypeEqual(toType(vm.mtyp).common(), toType(tm.typ).common()) { if i++; i >= len(t.methods) { return true } @@ -572,7 +572,7 @@ func implements(T, V *rtype) bool { // and the ideal constant rules (no ideal constants at run time). func directlyAssignable(T, V *rtype) bool { // x's type V is identical to T? - if T == V { + if rtypeEqual(T, V) { return true } @@ -599,7 +599,7 @@ func haveIdenticalType(T, V Type, cmpTags bool) bool { } func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { - if T == V { + if rtypeEqual(T, V) { return true } diff --git a/libgo/go/reflect/eqtype.go b/libgo/go/reflect/eqtype.go new file mode 100644 index 0000000..5639bc5 --- /dev/null +++ b/libgo/go/reflect/eqtype.go @@ -0,0 +1,24 @@ +// 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 !aix !gccgo + +package reflect + +// rtypeEqual returns true if both rtypes are identical. +func rtypeEqual(t1, t2 *rtype) bool { + return t1 == t2 +} + +// typeEqual returns true if both Types are identical. +func typeEqual(t1, t2 Type) bool { + return t1 == t2 +} + +func toType(p *rtype) Type { + if p == nil { + return nil + } + return p +} diff --git a/libgo/go/reflect/eqtype_aix_gccgo.go b/libgo/go/reflect/eqtype_aix_gccgo.go new file mode 100644 index 0000000..7afbf10 --- /dev/null +++ b/libgo/go/reflect/eqtype_aix_gccgo.go @@ -0,0 +1,74 @@ +// 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 aix,gccgo + +// AIX linker isn't able to merge identical type descriptors coming from +// different objects. Thus, two rtypes might have two different pointers +// even if they are the same. Thus, instead of pointer equality, string +// field is checked. + +package reflect + +import ( + "sync" +) + +// rtypeEqual returns true if both rtypes are identical. +func rtypeEqual(t1, t2 *rtype) bool { + switch { + case t1 == t2: + return true + case t1 == nil || t2 == nil: + return false + case t1.kind != t2.kind || t1.hash != t2.hash: + return false + default: + return t1.String() == t2.String() + } +} + +// typeEqual returns true if both Types are identical. +func typeEqual(t1, t2 Type) bool { + return rtypeEqual(t1.common(), t2.common()) +} + +// toType converts from a *rtype to a Type that can be returned +// to the client of package reflect. The only concern is that +// a nil *rtype must be replaced by a nil Type. +// On AIX, as type duplications can occur, it also ensure that +// multiple *rtype for the same type are coalesced into a single +// Type. + +var canonicalType = make(map[string]Type) + +var canonicalTypeLock sync.RWMutex + +func canonicalize(t Type) Type { + if t == nil { + return nil + } + s := t.rawString() + canonicalTypeLock.RLock() + if r, ok := canonicalType[s]; ok { + canonicalTypeLock.RUnlock() + return r + } + canonicalTypeLock.RUnlock() + canonicalTypeLock.Lock() + if r, ok := canonicalType[s]; ok { + canonicalTypeLock.Unlock() + return r + } + canonicalType[s] = t + canonicalTypeLock.Unlock() + return t +} + +func toType(p *rtype) Type { + if p == nil { + return nil + } + return canonicalize(p) +} diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go index 2ce1901f..73c09d4 100644 --- a/libgo/go/reflect/type.go +++ b/libgo/go/reflect/type.go @@ -1129,7 +1129,7 @@ func (t *rtype) ptrTo() *rtype { // Look in known types. s := "*" + *t.string if tt := lookupType(s); tt != nil { - p := (*ptrType)(unsafe.Pointer(tt)) + p := (*ptrType)(unsafe.Pointer(toType(tt).(*rtype))) if p.elem == t { pi, _ := ptrMap.LoadOrStore(t, p) return &pi.(*ptrType).rtype @@ -1158,7 +1158,9 @@ func (t *rtype) ptrTo() *rtype { pp.ptrToThis = nil pp.elem = t - pi, _ := ptrMap.LoadOrStore(t, &pp) + q := toType(&pp.rtype).(*rtype) + p := (*ptrType)(unsafe.Pointer(q)) + pi, _ := ptrMap.LoadOrStore(t, p) return &pi.(*ptrType).rtype } @@ -1273,7 +1275,7 @@ func specialChannelAssignability(T, V *rtype) bool { // and the ideal constant rules (no ideal constants at run time). func directlyAssignable(T, V *rtype) bool { // x's type V is identical to T? - if T == V { + if rtypeEqual(T, V) { return true } @@ -1304,7 +1306,7 @@ func haveIdenticalType(T, V Type, cmpTags bool) bool { } func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { - if T == V { + if rtypeEqual(T, V) { return true } @@ -1449,7 +1451,7 @@ func ChanOf(dir ChanDir, t Type) Type { s = "chan " + *typ.string } if tt := lookupType(s); tt != nil { - ch := (*chanType)(unsafe.Pointer(tt)) + ch := (*chanType)(unsafe.Pointer(toType(tt).(*rtype))) if ch.elem == typ && ch.dir == uintptr(dir) { ti, _ := lookupCache.LoadOrStore(ckey, tt) return ti.(Type) @@ -1481,7 +1483,7 @@ func ChanOf(dir ChanDir, t Type) Type { ch.uncommonType = nil ch.ptrToThis = nil - ti, _ := lookupCache.LoadOrStore(ckey, &ch.rtype) + ti, _ := lookupCache.LoadOrStore(ckey, toType(&ch.rtype).(*rtype)) return ti.(Type) } @@ -1508,7 +1510,7 @@ func MapOf(key, elem Type) Type { // Look in known types. s := "map[" + *ktyp.string + "]" + *etyp.string if tt := lookupType(s); tt != nil { - mt := (*mapType)(unsafe.Pointer(tt)) + mt := (*mapType)(unsafe.Pointer(toType(tt).(*rtype))) if mt.key == ktyp && mt.elem == etyp { ti, _ := lookupCache.LoadOrStore(ckey, tt) return ti.(Type) @@ -1559,7 +1561,7 @@ func MapOf(key, elem Type) Type { mt.flags |= 16 } - ti, _ := lookupCache.LoadOrStore(ckey, &mt.rtype) + ti, _ := lookupCache.LoadOrStore(ckey, toType(&mt.rtype).(*rtype)) return ti.(Type) } @@ -1648,7 +1650,7 @@ func FuncOf(in, out []Type, variadic bool) Type { ft.string = &str ft.uncommonType = nil ft.ptrToThis = nil - return addToCache(&ft.rtype) + return addToCache(toType(&ft.rtype).(*rtype)) } // funcStr builds a string representation of a funcType. @@ -1909,7 +1911,7 @@ func SliceOf(t Type) Type { // Look in known types. s := "[]" + *typ.string if tt := lookupType(s); tt != nil { - slice := (*sliceType)(unsafe.Pointer(tt)) + slice := (*sliceType)(unsafe.Pointer(toType(tt).(*rtype))) if slice.elem == typ { ti, _ := lookupCache.LoadOrStore(ckey, tt) return ti.(Type) @@ -1930,7 +1932,7 @@ func SliceOf(t Type) Type { slice.uncommonType = nil slice.ptrToThis = nil - ti, _ := lookupCache.LoadOrStore(ckey, &slice.rtype) + ti, _ := lookupCache.LoadOrStore(ckey, toType(&slice.rtype).(*rtype)) return ti.(Type) } @@ -2234,7 +2236,7 @@ func StructOf(fields []StructField) Type { typ.uncommonType = nil typ.ptrToThis = nil - return addToCache(&typ.rtype) + return addToCache(toType(&typ.rtype).(*rtype)) } // runtimeStructField takes a StructField value passed to StructOf and @@ -2330,7 +2332,7 @@ func ArrayOf(count int, elem Type) Type { // Look in known types. s := "[" + strconv.Itoa(count) + "]" + *typ.string if tt := lookupType(s); tt != nil { - array := (*arrayType)(unsafe.Pointer(tt)) + array := (*arrayType)(unsafe.Pointer(toType(tt).(*rtype))) if array.elem == typ { ti, _ := lookupCache.LoadOrStore(ckey, tt) return ti.(Type) @@ -2446,7 +2448,7 @@ func ArrayOf(count int, elem Type) Type { array.kind &^= kindDirectIface } - ti, _ := lookupCache.LoadOrStore(ckey, &array.rtype) + ti, _ := lookupCache.LoadOrStore(ckey, toType(&array.rtype).(*rtype)) return ti.(Type) } @@ -2458,16 +2460,6 @@ func appendVarint(x []byte, v uintptr) []byte { return x } -// toType converts from a *rtype to a Type that can be returned -// to the client of package reflect. The only concern is that -// a nil *rtype must be replaced by a nil Type. -func toType(p *rtype) Type { - if p == nil { - return nil - } - return p -} - // Look up a compiler-generated type descriptor. // Implemented in runtime. func lookupType(s string) *rtype diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go index e60f84f..64f7432 100644 --- a/libgo/go/reflect/value.go +++ b/libgo/go/reflect/value.go @@ -1785,7 +1785,7 @@ type SliceHeader struct { } func typesMustMatch(what string, t1, t2 Type) { - if t1 != t2 { + if !typeEqual(t1, t2) { panic(what + ": " + t1.String() + " != " + t2.String()) } } -- cgit v1.1 From 7355c1df55e28f3298b14a621968f9a27fdcd2bf Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Tue, 13 Oct 2020 07:06:11 +0000 Subject: syscall: port fix for netbsd unix sockets from upstream NetBSD does not include the null terminator when in its reported socket length. Port the upstream bugfix for the issue (#6627). This was likely missed during the usual upstream merge because the gc and gccgo socket implementations have diverged quite a bit. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/261741 --- libgo/go/syscall/socket_bsd.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'libgo') diff --git a/libgo/go/syscall/socket_bsd.go b/libgo/go/syscall/socket_bsd.go index f62457f..40637bc 100644 --- a/libgo/go/syscall/socket_bsd.go +++ b/libgo/go/syscall/socket_bsd.go @@ -52,13 +52,19 @@ func (sa *RawSockaddrUnix) setLen(n int) { } func (sa *RawSockaddrUnix) getLen() (int, error) { - if sa.Len < 3 || sa.Len > SizeofSockaddrUnix { + if sa.Len < 2 || sa.Len > SizeofSockaddrUnix { return 0, EINVAL } - n := int(sa.Len) - 3 // subtract leading Family, Len, terminating NUL. + + // Some BSDs include the trailing NUL in the length, whereas + // others do not. Work around this by subtracting the leading + // family and len. The path is then scanned to see if a NUL + // terminator still exists within the length. + n := int(sa.Len) - 2 // subtract leading Family, Len for i := 0; i < n; i++ { if sa.Path[i] == 0 { - // found early NUL; assume Len is overestimating. + // found early NUL; assume Len included the NUL + // or was overestimating. n = i break } -- cgit v1.1 From 7e5aeda340d71a84fbd15504e848a949b2a00d5a Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Tue, 13 Oct 2020 06:51:30 +0000 Subject: runtime: populate signal PC on NetBSD The NetBSD libc provides an architecture-independent macro that can extract the PC from a ucontext struct. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/261740 --- libgo/runtime/go-signal.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libgo') diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c index b429fdb..d30d160 100644 --- a/libgo/runtime/go-signal.c +++ b/libgo/runtime/go-signal.c @@ -229,6 +229,8 @@ getSiginfo(siginfo_t *info, void *context __attribute__((unused))) ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.jmp_context.iar; #elif defined(__aarch64__) && defined(__linux__) ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.pc; +#elif defined(__NetBSD__) + ret.sigpc = _UC_MACHINE_PC(((ucontext_t*)(context))); #endif if (ret.sigpc == 0) { -- cgit v1.1 From ca56d576241c6783eb36eea526b42c4f3fbf697b Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Tue, 13 Oct 2020 07:17:55 +0000 Subject: runtime: correct semaphore implementation on netbsd NetBSD's semaphores use the underlying lighweight process mechanism (LWP) on NetBSD, rather than pthreads. This means the m.prodcid needs to be set to the LWP ID rather than the pthread ID in order for unpark notifications to get sent to the right place. Introduce a new getProcID() method that selects the correct ID for the platform. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/261742 --- libgo/go/runtime/os_aix.go | 4 ++++ libgo/go/runtime/os_gccgo.go | 3 +-- libgo/go/runtime/os_hurd.go | 4 ++++ libgo/go/runtime/os_linux.go | 4 ++++ libgo/go/runtime/os_netbsd.go | 17 ++++++++++++----- libgo/go/runtime/os_solaris.go | 4 ++++ 6 files changed, 29 insertions(+), 7 deletions(-) (limited to 'libgo') diff --git a/libgo/go/runtime/os_aix.go b/libgo/go/runtime/os_aix.go index 951aeb6..f49b83c 100644 --- a/libgo/go/runtime/os_aix.go +++ b/libgo/go/runtime/os_aix.go @@ -21,6 +21,10 @@ type mOS struct { waitsema uintptr // semaphore for parking on locks } +func getProcID() uint64 { + return uint64(gettid()) +} + //extern malloc func libc_malloc(uintptr) unsafe.Pointer diff --git a/libgo/go/runtime/os_gccgo.go b/libgo/go/runtime/os_gccgo.go index ab19022..a8859c0 100644 --- a/libgo/go/runtime/os_gccgo.go +++ b/libgo/go/runtime/os_gccgo.go @@ -27,8 +27,7 @@ func mpreinit(mp *m) { func minit() { minitSignals() - // FIXME: only works on linux for now. - getg().m.procid = uint64(gettid()) + getg().m.procid = getProcID() } // Called from dropm to undo the effect of an minit. diff --git a/libgo/go/runtime/os_hurd.go b/libgo/go/runtime/os_hurd.go index b3c6f80..1613b41 100644 --- a/libgo/go/runtime/os_hurd.go +++ b/libgo/go/runtime/os_hurd.go @@ -18,6 +18,10 @@ type mOS struct { waitsema uintptr // semaphore for parking on locks } +func getProcID() uint64 { + return uint64(gettid()) +} + //extern malloc func libc_malloc(uintptr) unsafe.Pointer diff --git a/libgo/go/runtime/os_linux.go b/libgo/go/runtime/os_linux.go index 5d55064..627b6d6 100644 --- a/libgo/go/runtime/os_linux.go +++ b/libgo/go/runtime/os_linux.go @@ -13,6 +13,10 @@ type mOS struct { unused byte } +func getProcID() uint64 { + return uint64(gettid()) +} + func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32 { return int32(syscall(_SYS_futex, uintptr(addr), uintptr(op), uintptr(val), uintptr(ts), uintptr(addr2), uintptr(val3))) } diff --git a/libgo/go/runtime/os_netbsd.go b/libgo/go/runtime/os_netbsd.go index 69d2c71..89a8d07 100644 --- a/libgo/go/runtime/os_netbsd.go +++ b/libgo/go/runtime/os_netbsd.go @@ -14,12 +14,19 @@ type mOS struct { waitsemacount uint32 } +func getProcID() uint64 { + return uint64(lwp_self()) +} + +//extern _lwp_self +func lwp_self() int32 + //go:noescape -//extern lwp_park +//extern _lwp_park func lwp_park(ts int32, rel int32, abstime *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32 //go:noescape -//extern lwp_unpark +//extern _lwp_unpark func lwp_unpark(lwp int32, hint unsafe.Pointer) int32 //go:noescape @@ -88,7 +95,7 @@ func semasleep(ns int64) int32 { tsp = &ts } ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil) - if ret == _ETIMEDOUT { + if ret != 0 && errno() == _ETIMEDOUT { return -1 } } @@ -101,10 +108,10 @@ func semawakeup(mp *m) { // "If the target LWP is not currently waiting, it will return // immediately upon the next call to _lwp_park()." ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.waitsemacount)) - if ret != 0 && ret != _ESRCH { + if ret != 0 && errno() != _ESRCH { // semawakeup can be called on signal stack. systemstack(func() { - print("thrwakeup addr=", &mp.waitsemacount, " sem=", mp.waitsemacount, " ret=", ret, "\n") + print("thrwakeup addr=", &mp.waitsemacount, " sem=", mp.waitsemacount, " errno=", errno(), "\n") }) } } diff --git a/libgo/go/runtime/os_solaris.go b/libgo/go/runtime/os_solaris.go index 63b5cd7..c568629 100644 --- a/libgo/go/runtime/os_solaris.go +++ b/libgo/go/runtime/os_solaris.go @@ -10,6 +10,10 @@ type mOS struct { waitsema uintptr // semaphore for parking on locks } +func getProcID() uint64 { + return uint64(gettid()) +} + //extern malloc func libc_malloc(uintptr) unsafe.Pointer -- cgit v1.1 From dc570700beab4080040884690deb6016090b4fa8 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Tue, 13 Oct 2020 06:36:43 +0000 Subject: libgo: export NetBSD-specific types in mksysinfo.sh The syscall package depends on many NetBSD-specific types on NetBSD. Teach mksysinfo.sh to export these types. This alone is not sufficient to get the syscall package to compile on NetBSD, but it's a start. Note that the IfMsgHdr type is recapitalized to IfMsghdr, which requires changes in the AIX port. The new capitalization is what's used by upstream in existing NetBSD-specific code and is more consistent with the capitalization of other C structs with the "hdr" suffix. Updates golang/go#38538. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/261739 --- libgo/config.h.in | 6 ++ libgo/configure | 2 +- libgo/configure.ac | 2 +- libgo/go/runtime/os_netbsd.go | 7 --- libgo/mksysinfo.sh | 139 ++++++++++++++++++++++++++++++++++++++++-- libgo/sysinfo.c | 54 ++++++++++++++++ 6 files changed, 195 insertions(+), 15 deletions(-) (limited to 'libgo') diff --git a/libgo/config.h.in b/libgo/config.h.in index bbb2516..532640b 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -174,6 +174,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NETPACKET_PACKET_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_BPF_H + /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_ARP_H @@ -294,6 +297,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSCALL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SYSCTL_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSINFO_H diff --git a/libgo/configure b/libgo/configure index 792ac6f..81331dd 100755 --- a/libgo/configure +++ b/libgo/configure @@ -15202,7 +15202,7 @@ $as_echo "#define HAVE_GETIPINFO 1" >>confdefs.h fi -for ac_header in port.h sched.h semaphore.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/event.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/ptrace.h linux/reboot.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h +for ac_header in port.h sched.h semaphore.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/event.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/sysctl.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/bpf.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/ptrace.h linux/reboot.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" diff --git a/libgo/configure.ac b/libgo/configure.ac index 9a10d33..f87ab65 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -580,7 +580,7 @@ AC_C_BIGENDIAN GCC_CHECK_UNWIND_GETIPINFO -AC_CHECK_HEADERS(port.h sched.h semaphore.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/event.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/ptrace.h linux/reboot.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h) +AC_CHECK_HEADERS(port.h sched.h semaphore.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/event.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/sysctl.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/bpf.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/ptrace.h linux/reboot.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h) AC_CHECK_HEADERS([netinet/icmp6.h], [], [], [#include diff --git a/libgo/go/runtime/os_netbsd.go b/libgo/go/runtime/os_netbsd.go index 89a8d07..9ebb652 100644 --- a/libgo/go/runtime/os_netbsd.go +++ b/libgo/go/runtime/os_netbsd.go @@ -33,13 +33,6 @@ func lwp_unpark(lwp int32, hint unsafe.Pointer) int32 //extern sysctl func sysctl(*uint32, uint32, *byte, *uintptr, *byte, uintptr) int32 -// From NetBSD's -const ( - _CTL_HW = 6 - _HW_NCPU = 3 - _HW_PAGESIZE = 7 -) - func getncpu() int32 { mib := [2]uint32{_CTL_HW, _HW_NCPU} out := uint32(0) diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh index 9671e39..607c97d 100755 --- a/libgo/mksysinfo.sh +++ b/libgo/mksysinfo.sh @@ -225,6 +225,22 @@ if ! grep '^const _AT_FDCWD = ' ${OUT} >/dev/null 2>&1; then echo "const _AT_FDCWD = -100" >> ${OUT} fi +# sysctl constants. +grep '^const _CTL' gen-sysinfo.go | + sed -e 's/^\(const \)_\(CTL[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} + grep '^const _SYSCTL' gen-sysinfo.go | + sed -e 's/^\(const \)_\(SYSCTL[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} + grep '^const _NET_RT' gen-sysinfo.go | + sed -e 's/^\(const \)_\(NET_RT[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} + +# The sysctlnode struct. +grep '^type _sysctlnode ' gen-sysinfo.go | \ + sed -e 's/_sysctlnode/Sysctlnode/' \ + -e 's/sysctl_flags/Flags/' \ + -e 's/sysctl_name/Name/' \ + -e 's/sysctl_num/Num/' \ + >> ${OUT} + # sysconf constants. grep '^const __SC' gen-sysinfo.go | sed -e 's/^\(const \)__\(SC[^= ]*\)\(.*\)$/\1\2 = __\2/' >> ${OUT} @@ -533,6 +549,7 @@ fi | sed -e 's/type _dirent64/type Dirent/' \ -e 's/d_name \[0+1\]/d_name [0+256]/' \ -e 's/d_name/Name/' \ -e 's/]int8/]byte/' \ + -e 's/d_fileno/Fileno/' \ -e 's/d_ino/Ino/' \ -e 's/d_namlen/Namlen/' \ -e 's/d_off/Off/' \ @@ -994,6 +1011,39 @@ grep '^type _rtgenmsg ' gen-sysinfo.go | \ -e 's/rtgen_family/Family/' \ >> ${OUT} +# The rt_msghdr struct. +grep '^type _rt_msghdr ' gen-sysinfo.go | \ + sed -e 's/_rt_msghdr/RtMsghdr/g' \ + -e 's/rtm_msglen/Msglen/' \ + -e 's/rtm_version/Version/' \ + -e 's/rtm_type/Type/' \ + -e 's/rtm_index/Index/' \ + -e 's/rtm_flags/Flags/' \ + -e 's/rtm_addrs/Addrs/' \ + -e 's/rtm_pid/Pid/' \ + -e 's/rtm_seq/Seq/' \ + -e 's/rtm_errno/Errno/' \ + -e 's/rtm_use/Use/' \ + -e 's/rtm_inits/Inits/' \ + -e 's/rtm_rmx/Rmx/' \ + -e 's/_rt_metrics/RtMetrics/' \ + >> ${OUT} + +# The rt_metrics struct. +grep '^type _rt_metrics ' gen-sysinfo.go | \ + sed -e 's/_rt_metrics/RtMetrics/g' \ + -e 's/rmx_locks/Locks/' \ + -e 's/rmx_mtu/Mtu/' \ + -e 's/rmx_hopcount/Hopcount/' \ + -e 's/rmx_recvpipe/Recvpipe/' \ + -e 's/rmx_sendpipe/Sendpipe/' \ + -e 's/rmx_ssthresh/Ssthresh/' \ + -e 's/rmx_rtt/Rtt/' \ + -e 's/rmx_rttvar/Rttvar/' \ + -e 's/rmx_expire/Expire/' \ + -e 's/rmx_pksent/Pksent/' \ + >> ${OUT} + # The routing message flags. grep '^const _RT_' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(RT_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} @@ -1020,9 +1070,14 @@ grep '^type _ifinfomsg ' gen-sysinfo.go | \ -e 's/ifi_change/Change/' \ >> ${OUT} -# The if_msghdr struct. +# The if_msghdr struct. Upstream uses inconsistent capitalization for this type +# on AIX, so we do too. +ifmsghdr_name=IfMsghdr +if test "${GOOS}" = "aix"; then + ifmsghdr_name=IfMsgHdr +fi grep '^type _if_msghdr ' gen-sysinfo.go | \ - sed -e 's/_if_msghdr/IfMsgHdr/' \ + sed -e "s/_if_msghdr/${ifmsghdr_name}/" \ -e 's/ifm_msglen/Msglen/' \ -e 's/ifm_version/Version/' \ -e 's/ifm_type/Type/' \ @@ -1032,6 +1087,17 @@ grep '^type _if_msghdr ' gen-sysinfo.go | \ -e 's/ifm_addrlen/Addrlen/' \ >> ${OUT} +# The if_announcemsghdr struct. +grep '^type _if_announcemsghdr ' gen-sysinfo.go | \ + sed -e 's/_if_announcemsghdr/IfAnnounceMsghdr/g' \ + -e 's/ifan_msglen/Msglen/' \ + -e 's/ifan_version/Version/' \ + -e 's/ifan_type/Type/' \ + -e 's/ifan_index/Index/' \ + -e 's/ifan_name/Name/' \ + -e 's/ifan_what/What/' \ + >> ${OUT} + # The interface information types and flags. grep '^const _IFA' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(IFA[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} @@ -1061,6 +1127,18 @@ grep '^type _ifaddrmsg ' gen-sysinfo.go | \ -e 's/ifa_index/Index/' \ >> ${OUT} +# The ifa_msghdr struct. +grep '^type _ifa_msghdr ' gen-sysinfo.go | \ + sed -e 's/_ifa_msghdr/IfaMsghdr/g' \ + -e 's/ifam_msglen/Msglen/' \ + -e 's/ifam_version/Version/' \ + -e 's/ifam_type/Type/' \ + -e 's/ifam_addrs/Addrs/' \ + -e 's/ifam_flags/Flags/' \ + -e 's/ifam_metric/Metric/' \ + -e 's/ifam_index/Index/' \ + >> ${OUT} + # The rtattr struct. grep '^type _rtattr ' gen-sysinfo.go | \ sed -e 's/_rtattr/RtAttr/' \ @@ -1068,6 +1146,54 @@ grep '^type _rtattr ' gen-sysinfo.go | \ -e 's/rta_type/Type/' \ >> ${OUT} +# The bpf_version struct. +grep '^type _bpf_version ' gen-sysinfo.go | \ + sed -e 's/_bpf_version/BpfVersion/g' \ + -e 's/bv_major/Major/' \ + -e 's/bv_minor/Minor/' \ + >> ${OUT} + +# The bpf_stat struct. +grep '^type _bpf_stat ' gen-sysinfo.go | \ + sed -e 's/_bpf_stat/BpfStat/g' \ + -e 's/bs_recv/Recv/' \ + -e 's/bs_drop/Drop/' \ + -e 's/bs_capt/Capt/' \ + -e 's/bs_padding/Padding/' \ + >> ${OUT} + +# The bpf_insn struct. +grep '^type _bpf_insn ' gen-sysinfo.go | \ + sed -e 's/_bpf_insn/BpfInsn/g' \ + -e 's/code/Code/' \ + -e 's/jt/Jt/' \ + -e 's/jf/Jf/' \ + -e 's/k/K/' \ + >> ${OUT} + +# The bpf_program struct. +grep '^type _bpf_program ' gen-sysinfo.go | \ + sed -e 's/_bpf_program/BpfProgram/g' \ + -e 's/bf_len/Len/' \ + -e 's/bf_insns/Insns/' \ + -e 's/_bpf_insn/BpfInsn/' \ + >> ${OUT} + +# The BPF ioctl constants. +grep '^const _BIOC' gen-sysinfo.go | \ + grep -v '_val =' | \ + sed -e 's/^\(const \)_\(BIOC[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} +for c in BIOCFLUSH BIOCGBLEN BIOCGDLT BIOCGETIF BIOCGHDRCMPLT BIOCGRTIMEOUT \ + BIOCGSTATS BIOCIMMEDIATE BIOCPROMISC BIOCSBLEN BIOCSDLT BIOCSETF \ + BIOCSETIF BIOCSHDRCMPLT BIOCSRTIMEOUT BIOCVERSION +do + if ! grep "^const ${c}" ${OUT} >/dev/null 2>&1; then + if grep "^const _${c}_val" ${OUT} >/dev/null 2>&1; then + echo "const ${c} = _${c}_val" >> ${OUT} + fi + fi +done + # The in_pktinfo struct. grep '^type _in_pktinfo ' gen-sysinfo.go | \ sed -e 's/_in_pktinfo/Inet4Pktinfo/' \ @@ -1344,10 +1470,11 @@ fi # Struct sizes. set cmsghdr Cmsghdr ip_mreq IPMreq ip_mreqn IPMreqn ipv6_mreq IPv6Mreq \ - ifaddrmsg IfAddrmsg ifinfomsg IfInfomsg in_pktinfo Inet4Pktinfo \ - in6_pktinfo Inet6Pktinfo inotify_event InotifyEvent linger Linger \ - msghdr Msghdr nlattr NlAttr nlmsgerr NlMsgerr nlmsghdr NlMsghdr \ - rtattr RtAttr rtgenmsg RtGenmsg rtmsg RtMsg rtnexthop RtNexthop \ + ifaddrmsg IfAddrmsg ifa_msghdr IfaMsghdr ifinfomsg IfInfomsg \ + if_msghdr IfMsghdr in_pktinfo Inet4Pktinfo in6_pktinfo Inet6Pktinfo \ + inotify_event InotifyEvent linger Linger msghdr Msghdr nlattr NlAttr \ + nlmsgerr NlMsgerr nlmsghdr NlMsghdr rtattr RtAttr rt_msghdr RtMsghdr \ + rtgenmsg RtGenmsg rtmsg RtMsg rtnexthop RtNexthop \ sock_filter SockFilter sock_fprog SockFprog ucred Ucred \ icmp6_filter ICMPv6Filter ip6_mtuinfo IPv6MTUInfo while test $# != 0; do diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c index 6ea990f..ba84071 100644 --- a/libgo/sysinfo.c +++ b/libgo/sysinfo.c @@ -47,6 +47,9 @@ #if defined(HAVE_SYS_SYSCALL_H) #include #endif +#if defined(HAVE_SYS_SYSCTL_H) +#include +#endif #if defined(HAVE_SYS_EPOLL_H) #include #endif @@ -117,6 +120,9 @@ #if defined(HAVE_LINUX_RTNETLINK_H) #include #endif +#if defined(HAVE_NET_BPF_H) +#include +#endif #if defined(HAVE_NET_IF_H) #include #endif @@ -279,6 +285,54 @@ enum { #ifdef NLA_HDRLEN NLA_HDRLEN_val = NLA_HDRLEN, #endif +#ifdef BIOCFLUSH + BIOCFLUSH_val = BIOCFLUSH, +#endif +#ifdef BIOCGBLEN + BIOCGBLEN_val = BIOCGBLEN, +#endif +#ifdef BIOCGDLT + BIOCGDLT_val = BIOCGDLT, +#endif +#ifdef BIOCGETIF + BIOCGETIF_val = BIOCGETIF, +#endif +#ifdef BIOCGHDRCMPLT + BIOCGHDRCMPLT_val = BIOCGHDRCMPLT, +#endif +#ifdef BIOCGRTIMEOUT + BIOCGRTIMEOUT_val = BIOCGRTIMEOUT, +#endif +#ifdef BIOCGSTATS + BIOCGSTATS_val = BIOCGSTATS, +#endif +#ifdef BIOCIMMEDIATE + BIOCIMMEDIATE_val = BIOCIMMEDIATE, +#endif +#ifdef BIOCPROMISC + BIOCPROMISC_val = BIOCPROMISC, +#endif +#ifdef BIOCSBLEN + BIOCSBLEN_val = BIOCSBLEN, +#endif +#ifdef BIOCSDLT + BIOCSDLT_val = BIOCSDLT, +#endif +#ifdef BIOCSETF + BIOCSETF_val = BIOCSETF, +#endif +#ifdef BIOCSETIF + BIOCSETIF_val = BIOCSETIF, +#endif +#ifdef BIOCSHDRCMPLT + BIOCSHDRCMPLT_val = BIOCSHDRCMPLT, +#endif +#ifdef BIOCSRTIMEOUT + BIOCSRTIMEOUT_val = BIOCSRTIMEOUT, +#endif +#ifdef BIOCVERSION + BIOCVERSION_val = BIOCVERSION, +#endif }; // SIOCGIFMTU can't be added in the above enum as it might -- cgit v1.1 From 28774a6015261a100c426d206154a98c0ca215ce Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Sat, 10 Oct 2020 16:26:54 +0000 Subject: libgo: print reason code if throwing unwind exception fails Calls to _Unwind_RaiseException and friends *can* return due to bugs in libgo or memory corruption. When this occurs, print a message to stderr with the reason code before aborting to aid debugging. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/261257 --- libgo/runtime/go-unwind.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'libgo') diff --git a/libgo/runtime/go-unwind.c b/libgo/runtime/go-unwind.c index ad3142c..16e0525 100644 --- a/libgo/runtime/go-unwind.c +++ b/libgo/runtime/go-unwind.c @@ -59,20 +59,22 @@ void rethrowException () { struct _Unwind_Exception *hdr; + _Unwind_Reason_Code reason; hdr = (struct _Unwind_Exception *) runtime_g()->exception; #ifdef __USING_SJLJ_EXCEPTIONS__ - _Unwind_SjLj_Resume_or_Rethrow (hdr); + reason = _Unwind_SjLj_Resume_or_Rethrow (hdr); #else #if defined(_LIBUNWIND_STD_ABI) - _Unwind_RaiseException (hdr); + reason = _Unwind_RaiseException (hdr); #else - _Unwind_Resume_or_Rethrow (hdr); + reason = _Unwind_Resume_or_Rethrow (hdr); #endif #endif /* Rethrowing the exception should not return. */ + runtime_printf ("failed to rethrow unwind exception (reason=%d)\n", reason); abort(); } @@ -105,6 +107,7 @@ throwException () { struct _Unwind_Exception *hdr; uintptr align; + _Unwind_Reason_Code reason; hdr = (struct _Unwind_Exception *)runtime_g ()->exception; @@ -119,12 +122,13 @@ throwException () hdr->exception_cleanup = NULL; #ifdef __USING_SJLJ_EXCEPTIONS__ - _Unwind_SjLj_RaiseException (hdr); + reason = _Unwind_SjLj_RaiseException (hdr); #else - _Unwind_RaiseException (hdr); + reason = _Unwind_RaiseException (hdr); #endif /* Raising an exception should not return. */ + runtime_printf ("failed to throw unwind exception (reason=%d)\n", reason); abort (); } -- cgit v1.1 From 6949fbefe28134744a86c5d7b8d9c17fcf3a16a0 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Wed, 14 Oct 2020 19:24:49 +0000 Subject: libgo: correct Makefile typo in path to x/net/route package Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/262342 --- libgo/Makefile.am | 2 +- libgo/Makefile.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'libgo') diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 76cdc8ef..26e8385 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -1096,7 +1096,7 @@ if LIBGO_IS_BSD $(eval $(call PACKAGE_template,golang.org/x/net/route)) golangorg_x_net_route_lo = \ - golang.org/net/route.lo + golang.org/x/net/route.lo endif diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 59a7083..d300ab6 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -1153,7 +1153,7 @@ extra_check_libs_cmd_vet_internal_cfg = $(abs_builddir)/libgotool.a @HAVE_STAT_TIMESPEC_TRUE@@LIBGO_IS_SOLARIS_TRUE@matchargs_os = --tag=solaristag @LIBGO_IS_SOLARIS_FALSE@matchargs_os = @LIBGO_IS_BSD_TRUE@golangorg_x_net_route_lo = \ -@LIBGO_IS_BSD_TRUE@ golang.org/net/route.lo +@LIBGO_IS_BSD_TRUE@ golang.org/x/net/route.lo @LIBGO_IS_SOLARIS_TRUE@golangorg_x_net_lif_lo = \ @LIBGO_IS_SOLARIS_TRUE@ golang.org/x/net/lif.lo -- cgit v1.1 From f33ac3b0cd9f88be8faadded88e40a511f01c32a Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Wed, 14 Oct 2020 19:02:12 +0000 Subject: runtime: use correct types in __go_ptrace shim Make the types of the addr and data arguments in the __go_ptrace shim match the types declared in Go and the types declared by the C ptrace function, i.e., void*. This avoids a warning about an implicit int-to-pointer cast on some platforms. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/262340 --- libgo/runtime/go-varargs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/runtime/go-varargs.c b/libgo/runtime/go-varargs.c index 9cb4a7e..d8f7dc5 100644 --- a/libgo/runtime/go-varargs.c +++ b/libgo/runtime/go-varargs.c @@ -122,7 +122,7 @@ __go_syscall6(uintptr_t flag, uintptr_t a1, uintptr_t a2, uintptr_t a3, // a variadic function within glibc. long -__go_ptrace(int request, pid_t pid, uintptr_t addr, uintptr_t data) +__go_ptrace(int request, pid_t pid, void *addr, void *data) { return ptrace (request, pid, addr, data); } -- cgit v1.1 From 522307281ce9042e0bb3044f4a162adcdee0f9f6 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Mon, 19 Oct 2020 02:19:04 +0000 Subject: syscall: remove Sendfile on NetBSD NetBSD does not support the sendfile syscall. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/263521 --- libgo/go/syscall/libcall_bsd.go | 31 ------------------------------- libgo/go/syscall/libcall_bsd_regfile.go | 2 +- libgo/go/syscall/libcall_bsd_sendfile.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 32 deletions(-) delete mode 100644 libgo/go/syscall/libcall_bsd.go create mode 100644 libgo/go/syscall/libcall_bsd_sendfile.go (limited to 'libgo') diff --git a/libgo/go/syscall/libcall_bsd.go b/libgo/go/syscall/libcall_bsd.go deleted file mode 100644 index 93f5710..0000000 --- a/libgo/go/syscall/libcall_bsd.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2015 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 ( - "internal/race" - "unsafe" -) - -func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { - if race.Enabled { - race.ReleaseMerge(unsafe.Pointer(&ioSync)) - } - var soff Offset_t - var psoff *Offset_t - if offset != nil { - soff = Offset_t(*offset) - psoff = &soff - } - written, err = sendfile(outfd, infd, psoff, count) - if offset != nil { - *offset = int64(soff) - } - return -} diff --git a/libgo/go/syscall/libcall_bsd_regfile.go b/libgo/go/syscall/libcall_bsd_regfile.go index 388c8a7..0b9d01f 100644 --- a/libgo/go/syscall/libcall_bsd_regfile.go +++ b/libgo/go/syscall/libcall_bsd_regfile.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,amd64 solaris,sparc64 +// +build darwin dragonfly freebsd openbsd solaris,amd64 solaris,sparc64 package syscall diff --git a/libgo/go/syscall/libcall_bsd_sendfile.go b/libgo/go/syscall/libcall_bsd_sendfile.go new file mode 100644 index 0000000..295a1f4 --- /dev/null +++ b/libgo/go/syscall/libcall_bsd_sendfile.go @@ -0,0 +1,31 @@ +// Copyright 2015 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 openbsd solaris + +// BSD sendfile support. + +package syscall + +import ( + "internal/race" + "unsafe" +) + +func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { + if race.Enabled { + race.ReleaseMerge(unsafe.Pointer(&ioSync)) + } + var soff Offset_t + var psoff *Offset_t + if offset != nil { + soff = Offset_t(*offset) + psoff = &soff + } + written, err = sendfile(outfd, infd, psoff, count) + if offset != nil { + *offset = int64(soff) + } + return +} -- cgit v1.1 From 7cf256c3c8d9375fea7a0f02c128fa084ae53396 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Mon, 19 Oct 2020 02:07:34 +0000 Subject: libgo: adjust NetBSD-specific types for stable syscall API The backwards-compatibility guarantees of the syscall package require some munging of the C API inferred by mksysinfo.sh. Specifically, the RTM_RESOLVE constant must be added if it is missing, and the stat_t struct must use the suffix "timespec" rather than "tim" for its time-related fields. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/263519 --- libgo/mksysinfo.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'libgo') diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh index 607c97d..deac5ce 100755 --- a/libgo/mksysinfo.sh +++ b/libgo/mksysinfo.sh @@ -507,6 +507,13 @@ if grep 'define st_dev st_fsid' gen-sysinfo.go > /dev/null 2>&1; then st_dev='-e s/st_fsid/Dev/' fi +# For historical reasons Go uses the suffix "timespec" instead of "tim" for +# stat_t's time fields on NetBSD. +st_times='-e s/st_atim/Atim/ -e s/st_mtim/Mtim/ -e s/st_ctim/Ctim/' +if test "${GOOS}" = "netbsd"; then + st_times='-e s/st_atim/Atimespec/ -e s/st_mtim/Mtimespec/ -e s/st_ctim/Ctimespec/' +fi + # The stat type. # Prefer largefile variant if available. stat=`grep '^type _stat64 ' gen-sysinfo.go || true` @@ -517,6 +524,7 @@ else fi | sed -e 's/type _stat64/type Stat_t/' \ -e 's/type _stat/type Stat_t/' \ ${st_dev} \ + ${st_times} \ -e 's/st_ino/Ino/g' \ -e 's/st_nlink/Nlink/' \ -e 's/st_mode/Mode/' \ @@ -526,9 +534,6 @@ fi | sed -e 's/type _stat64/type Stat_t/' \ -e 's/st_size/Size/' \ -e 's/st_blksize/Blksize/' \ -e 's/st_blocks/Blocks/' \ - -e 's/st_atim/Atim/' \ - -e 's/st_mtim/Mtim/' \ - -e 's/st_ctim/Ctim/' \ -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1Timeval\2/g' \ -e 's/\([^a-zA-Z0-9_]\)_timespec_t\([^a-zA-Z0-9_]\)/\1Timespec\2/g' \ -e 's/\([^a-zA-Z0-9_]\)_st_timespec_t\([^a-zA-Z0-9_]\)/\1StTimespec\2/g' \ @@ -1055,6 +1060,13 @@ grep '^const _RTCF' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(RTCF[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} grep '^const _RTM' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(RTM[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} +if test "${GOOS}" = "netbsd"; then + if ! grep "RTM_RESOLVE" ${OUT} >/dev/null 2>&1; then + # NetBSD 8.0 removed RTM_RESOLVE, but it is part of the syscall package's + # stable API, so add it manually. + echo "const RTM_RESOLVE = 0xb" >> ${OUT} + fi +fi grep '^const _RTN' gen-sysinfo.go | \ sed -e 's/^\(const \)_\(RTN[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} grep '^const _RTPROT' gen-sysinfo.go | \ -- cgit v1.1 From 2ab1fc7a322e2582772f0e4ed916508c890175e3 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Sat, 10 Oct 2020 00:06:36 +0000 Subject: syscall: import upstream code for BSD sockets and sysctls Import some missing upstream code for BSD sockets and sysctls and adapt it for gccgo. Updates golang/go#38538. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/261137 --- libgo/go/syscall/route_bsd.go | 2 +- libgo/go/syscall/socket_bsd.go | 41 +++++++++++++++++++++++++ libgo/go/syscall/syscall_netbsd.go | 61 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/go/syscall/route_bsd.go b/libgo/go/syscall/route_bsd.go index b364eea..0c32594 100644 --- a/libgo/go/syscall/route_bsd.go +++ b/libgo/go/syscall/route_bsd.go @@ -18,7 +18,7 @@ var ( // Round the length of a raw sockaddr up to align it properly. func rsaAlignOf(salen int) int { - salign := sizeofPtr + salign := int(sizeofPtr) if darwin64Bit { // Darwin kernels require 32-bit aligned access to // routing facilities. diff --git a/libgo/go/syscall/socket_bsd.go b/libgo/go/syscall/socket_bsd.go index 40637bc..b230a32 100644 --- a/libgo/go/syscall/socket_bsd.go +++ b/libgo/go/syscall/socket_bsd.go @@ -13,6 +13,7 @@ import "unsafe" const SizeofSockaddrInet4 = 16 const SizeofSockaddrInet6 = 28 const SizeofSockaddrUnix = 110 +const SizeofSockaddrDatalink = 20 type RawSockaddrInet4 struct { Len uint8 @@ -76,6 +77,46 @@ func (sa *RawSockaddrUnix) adjustAbstract(sl Socklen_t) Socklen_t { return sl } +type SockaddrDatalink struct { + Len uint8 + Family uint8 + Index uint16 + Type uint8 + Nlen uint8 + Alen uint8 + Slen uint8 + Data [12]int8 + raw RawSockaddrDatalink +} + +func (sa *SockaddrDatalink) sockaddr() (*RawSockaddrAny, Socklen_t, error) { + if sa.Index == 0 { + return nil, 0, EINVAL + } + sa.raw.Len = sa.Len + sa.raw.Family = AF_LINK + sa.raw.Index = sa.Index + sa.raw.Type = sa.Type + sa.raw.Nlen = sa.Nlen + sa.raw.Alen = sa.Alen + sa.raw.Slen = sa.Slen + for i := 0; i < len(sa.raw.Data); i++ { + sa.raw.Data[i] = sa.Data[i] + } + return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrDatalink, nil +} + +type RawSockaddrDatalink struct { + Len uint8 + Family uint8 + Index uint16 + Type uint8 + Nlen uint8 + Alen uint8 + Slen uint8 + Data [12]int8 +} + type RawSockaddr struct { Len uint8 Family uint8 diff --git a/libgo/go/syscall/syscall_netbsd.go b/libgo/go/syscall/syscall_netbsd.go index c67550a..bbc6799 100644 --- a/libgo/go/syscall/syscall_netbsd.go +++ b/libgo/go/syscall/syscall_netbsd.go @@ -17,3 +17,64 @@ func direntReclen(buf []byte) (uint64, bool) { func direntNamlen(buf []byte) (uint64, bool) { return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) } + +func sysctlNodes(mib []_C_int) (nodes []Sysctlnode, err error) { + var olen uintptr + + // Get a list of all sysctl nodes below the given MIB by performing + // a sysctl for the given MIB with CTL_QUERY appended. + mib = append(mib, CTL_QUERY) + qnode := Sysctlnode{Flags: SYSCTL_VERS_1} + qp := (*byte)(unsafe.Pointer(&qnode)) + sz := unsafe.Sizeof(qnode) + if err = sysctl(mib, nil, &olen, qp, sz); err != nil { + return nil, err + } + + // Now that we know the size, get the actual nodes. + nodes = make([]Sysctlnode, olen/sz) + np := (*byte)(unsafe.Pointer(&nodes[0])) + if err = sysctl(mib, np, &olen, qp, sz); err != nil { + return nil, err + } + + return nodes, nil +} + +func nametomib(name string) (mib []_C_int, err error) { + // Split name into components. + var parts []string + last := 0 + for i := 0; i < len(name); i++ { + if name[i] == '.' { + parts = append(parts, name[last:i]) + last = i + 1 + } + } + parts = append(parts, name[last:]) + + // Discover the nodes and construct the MIB OID. + for partno, part := range parts { + nodes, err := sysctlNodes(mib) + if err != nil { + return nil, err + } + for _, node := range nodes { + n := make([]byte, 0) + for i := range node.Name { + if node.Name[i] != 0 { + n = append(n, byte(node.Name[i])) + } + } + if string(n) == part { + mib = append(mib, _C_int(node.Num)) + break + } + } + if len(mib) != partno+1 { + return nil, EINVAL + } + } + + return mib, nil +} -- cgit v1.1 From 439407aa2c678a96bd5b430ab9c335e65beb5751 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Sun, 18 Oct 2020 19:28:54 +0000 Subject: syscall: only compile ptrace varargs shim on Linux Only compile the __go_ptrace varargs shim on Linux to avoid compilation failures on some other platforms. The C ptrace function is not entirely portable (e.g., NetBSD has `int data` instead of `void* data`), and so far Linux is the only platform that needs the varargs shim. Additionally, make the types in the ptrace and raw_ptrace function declarations match. This makes it more clear that the only difference between the two is that calls via the former are allowed to block while calls via the latter are not. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/263517 --- libgo/go/syscall/exec_bsd.go | 2 +- libgo/go/syscall/exec_linux.go | 2 +- libgo/go/syscall/exec_stubs.go | 2 +- libgo/go/syscall/libcall_aix.go | 2 +- libgo/go/syscall/libcall_glibc.go | 3 --- libgo/go/syscall/libcall_hurd.go | 2 +- libgo/go/syscall/libcall_irix.go | 2 +- libgo/go/syscall/libcall_linux.go | 5 ++++- libgo/go/syscall/libcall_solaris_386.go | 2 +- libgo/go/syscall/libcall_solaris_amd64.go | 2 +- libgo/go/syscall/libcall_solaris_sparc.go | 2 +- libgo/go/syscall/libcall_solaris_sparc64.go | 2 +- libgo/runtime/go-varargs.c | 7 +++---- 13 files changed, 17 insertions(+), 18 deletions(-) (limited to 'libgo') diff --git a/libgo/go/syscall/exec_bsd.go b/libgo/go/syscall/exec_bsd.go index 7e06943..ca7fdc0 100644 --- a/libgo/go/syscall/exec_bsd.go +++ b/libgo/go/syscall/exec_bsd.go @@ -93,7 +93,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr // Enable tracing if requested. if sys.Ptrace { - err1 = raw_ptrace(_PTRACE_TRACEME, 0, nil, nil) + err1 = raw_ptrace(_PTRACE_TRACEME, 0, 0, 0) if err1 != 0 { goto childerror } diff --git a/libgo/go/syscall/exec_linux.go b/libgo/go/syscall/exec_linux.go index 2f0a34f..3897581 100644 --- a/libgo/go/syscall/exec_linux.go +++ b/libgo/go/syscall/exec_linux.go @@ -538,7 +538,7 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att // Do this right before exec so that we don't unnecessarily trace the runtime // setting up after the fork. See issue #21428. if sys.Ptrace { - err1 = raw_ptrace(_PTRACE_TRACEME, 0, nil, nil) + err1 = raw_ptrace(_PTRACE_TRACEME, 0, 0, 0) if err1 != 0 { goto childerror } diff --git a/libgo/go/syscall/exec_stubs.go b/libgo/go/syscall/exec_stubs.go index e95b415..c837cf7 100644 --- a/libgo/go/syscall/exec_stubs.go +++ b/libgo/go/syscall/exec_stubs.go @@ -30,6 +30,6 @@ func (w WaitStatus) Signal() int { return 0 } func (w WaitStatus) StopSignal() int { return 0 } func (w WaitStatus) TrapCause() int { return 0 } -func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno { +func raw_ptrace(request int, pid int, addr uintptr, data uintptr) Errno { return ENOSYS } diff --git a/libgo/go/syscall/libcall_aix.go b/libgo/go/syscall/libcall_aix.go index 27b469e..92c7f3c 100644 --- a/libgo/go/syscall/libcall_aix.go +++ b/libgo/go/syscall/libcall_aix.go @@ -19,7 +19,7 @@ const SYS_EXECVE = 0 //sys ptrace64(request int, id int64, addr int64, data int, buff uintptr) (err error) //ptrace64(request _C_int, id int64, addr int64, data _C_int, buff *byte) _C_int -func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno { +func raw_ptrace(request int, pid int, addr uintptr, data uintptr) Errno { if request == _PTRACE_TRACEME { // Convert to AIX ptrace call. err := ptrace64(_PT_TRACE_ME, 0, 0, 0, 0) diff --git a/libgo/go/syscall/libcall_glibc.go b/libgo/go/syscall/libcall_glibc.go index 823343d..a32d696 100644 --- a/libgo/go/syscall/libcall_glibc.go +++ b/libgo/go/syscall/libcall_glibc.go @@ -31,9 +31,6 @@ func Futimes(fd int, tv []Timeval) (err error) { return Utimes("/proc/self/fd/"+itoa(fd), tv) } -//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) -//__go_ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long - //sys accept4(fd int, sa *RawSockaddrAny, len *Socklen_t, flags int) (nfd int, err error) //accept4(fd _C_int, sa *RawSockaddrAny, len *Socklen_t, flags _C_int) _C_int diff --git a/libgo/go/syscall/libcall_hurd.go b/libgo/go/syscall/libcall_hurd.go index f0e038c..44ff46d 100644 --- a/libgo/go/syscall/libcall_hurd.go +++ b/libgo/go/syscall/libcall_hurd.go @@ -7,7 +7,7 @@ package syscall // Dummy function -func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno { +func raw_ptrace(request int, pid int, addr uintptr, data uintptr) Errno { return ENOSYS } diff --git a/libgo/go/syscall/libcall_irix.go b/libgo/go/syscall/libcall_irix.go index 9b6cdcc..9880766 100644 --- a/libgo/go/syscall/libcall_irix.go +++ b/libgo/go/syscall/libcall_irix.go @@ -6,5 +6,5 @@ package syscall -//sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno) +//sysnb raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) //ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long diff --git a/libgo/go/syscall/libcall_linux.go b/libgo/go/syscall/libcall_linux.go index 78fda0e..96974bd 100644 --- a/libgo/go/syscall/libcall_linux.go +++ b/libgo/go/syscall/libcall_linux.go @@ -10,7 +10,10 @@ import ( "unsafe" ) -//sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno) +//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) +//__go_ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long + +//sysnb raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) //__go_ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { diff --git a/libgo/go/syscall/libcall_solaris_386.go b/libgo/go/syscall/libcall_solaris_386.go index 20eba22..ef86f09 100644 --- a/libgo/go/syscall/libcall_solaris_386.go +++ b/libgo/go/syscall/libcall_solaris_386.go @@ -8,5 +8,5 @@ package syscall //sysnb Uname(buf *Utsname) (err error) //_nuname(buf *Utsname) _C_int -//sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno) +//sysnb raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) //ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long diff --git a/libgo/go/syscall/libcall_solaris_amd64.go b/libgo/go/syscall/libcall_solaris_amd64.go index 69b11ba..f44025e 100644 --- a/libgo/go/syscall/libcall_solaris_amd64.go +++ b/libgo/go/syscall/libcall_solaris_amd64.go @@ -5,6 +5,6 @@ package syscall // 64-bit ptrace(3C) doesn't exist -func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno { +func raw_ptrace(request int, pid int, addr uintptr, data uintptr) Errno { return ENOSYS } diff --git a/libgo/go/syscall/libcall_solaris_sparc.go b/libgo/go/syscall/libcall_solaris_sparc.go index 50863fa..3d50309 100644 --- a/libgo/go/syscall/libcall_solaris_sparc.go +++ b/libgo/go/syscall/libcall_solaris_sparc.go @@ -4,5 +4,5 @@ package syscall -//sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno) +//sysnb raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno) //ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long diff --git a/libgo/go/syscall/libcall_solaris_sparc64.go b/libgo/go/syscall/libcall_solaris_sparc64.go index 69b11ba..f44025e 100644 --- a/libgo/go/syscall/libcall_solaris_sparc64.go +++ b/libgo/go/syscall/libcall_solaris_sparc64.go @@ -5,6 +5,6 @@ package syscall // 64-bit ptrace(3C) doesn't exist -func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno { +func raw_ptrace(request int, pid int, addr uintptr, data uintptr) Errno { return ENOSYS } diff --git a/libgo/runtime/go-varargs.c b/libgo/runtime/go-varargs.c index d8f7dc5..f848608 100644 --- a/libgo/runtime/go-varargs.c +++ b/libgo/runtime/go-varargs.c @@ -114,12 +114,11 @@ __go_syscall6(uintptr_t flag, uintptr_t a1, uintptr_t a2, uintptr_t a3, #endif -// AIX ptrace is really different from Linux ptrace. Let syscall -// package handles it. -#if defined(HAVE_SYS_PTRACE_H) && !defined(_AIX) + +#if defined(HAVE_SYS_PTRACE_H) && defined(__linux__) // Despite documented appearances, this is actually implemented as -// a variadic function within glibc. +// a variadic function within glibc on Linux. long __go_ptrace(int request, pid_t pid, void *addr, void *data) -- cgit v1.1 From 27f7ab27d1a514eaf538ae01840b42c6d12cb28f Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Wed, 21 Oct 2020 03:00:04 -0400 Subject: net/http/cgi: merge upstream changes to default env vars Incorporate upstream modifications to the cgi package's set of rules about which environment variables should be inherited by child processes by default on each platform. In particular this permits tests to pass on NetBSD by preserving the value of the LD_LIBRARY_PATH environment variable. This is a partial backport of the following upstream CLs: https://golang.org/cl/263802 https://golang.org/cl/263577 https://golang.org/cl/254740 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/264097 --- libgo/go/net/http/cgi/host.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libgo') diff --git a/libgo/go/net/http/cgi/host.go b/libgo/go/net/http/cgi/host.go index 863f406..eff67ca 100644 --- a/libgo/go/net/http/cgi/host.go +++ b/libgo/go/net/http/cgi/host.go @@ -37,15 +37,15 @@ var trailingPort = regexp.MustCompile(`:([0-9]+)$`) var osDefaultInheritEnv = func() []string { switch runtime.GOOS { - case "darwin": + case "darwin", "ios": return []string{"DYLD_LIBRARY_PATH"} - case "linux", "freebsd", "openbsd": + case "linux", "freebsd", "netbsd", "openbsd": return []string{"LD_LIBRARY_PATH"} case "hpux": return []string{"LD_LIBRARY_PATH", "SHLIB_PATH"} case "irix": return []string{"LD_LIBRARY_PATH", "LD_LIBRARYN32_PATH", "LD_LIBRARY64_PATH"} - case "solaris": + case "illumos", "solaris": return []string{"LD_LIBRARY_PATH", "LD_LIBRARY_PATH_32", "LD_LIBRARY_PATH_64"} case "windows": return []string{"SystemRoot", "COMSPEC", "PATHEXT", "WINDIR"} -- cgit v1.1