libgo: update to go1.15rc1

Change-Id: Iab1ff0b7d52efdb3310c859605d2cfc75c1a903e
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/245157
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/libgo/MERGE b/libgo/MERGE
index 4f85893..ad43e29 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-edfd6f28486017dcb136cd3f3ec252706d4b326e
+3e8f6b0791a670e52d25d76813d669daa68acfb4
 
 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/Makefile.am b/libgo/Makefile.am
index 52a8330..88ea272 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -391,6 +391,11 @@
 toolexeclibgotexttemplate_DATA = \
 	text/template/parse.gox
 
+toolexeclibgotimedir = $(toolexeclibgodir)/time
+
+toolexeclibgotime_DATA = \
+	time/tzdata.gox
+
 toolexeclibgounicodedir = $(toolexeclibgodir)/unicode
 
 toolexeclibgounicode_DATA = \
@@ -400,7 +405,8 @@
 # Some internal packages are needed to bootstrap the gc toolchain.
 toolexeclibgointernaldir = $(toolexeclibgodir)/internal
 toolexeclibgointernal_DATA = \
-	internal/reflectlite.gox
+	internal/reflectlite.gox \
+	internal/unsafeheader.gox
 
 # Some packages are only needed for tests, so unlike the other
 # internal packages nothing will explicitly depend on them.
@@ -409,11 +415,11 @@
 	golang.org/x/net/nettest.gox \
 	internal/cfg.gox \
 	internal/obscuretestdata.gox \
+	internal/profile.gox \
 	internal/testenv.gox \
 	internal/trace.gox \
 	net/internal/socktest.gox \
-	os/signal/internal/pty.gox \
-	runtime/pprof/internal/profile.gox
+	os/signal/internal/pty.gox
 
 if LIBGO_IS_RTEMS
 rtems_task_variable_add_file = runtime/rtems-task-variable-add.c
@@ -706,9 +712,9 @@
 endif
 
 if LIBGO_IS_X86
-golangorg_x_sys_cpu_gccgo_lo = golang.org/x/sys/cpu_gccgo.lo
+golangorg_x_sys_cpu_gccgo_x86_lo = golang.org/x/sys/cpu_gccgo_x86.lo
 else
-golangorg_x_sys_cpu_gccgo_lo =
+golangorg_x_sys_cpu_gccgo_x86_lo =
 endif
 
 PACKAGES = $(shell cat $(srcdir)/libgo-packages.txt)
@@ -728,7 +734,7 @@
 	runtime/internal/atomic_c.lo \
 	sync/atomic_c.lo \
 	internal/cpu/cpu_gccgo.lo \
-	$(golangorg_x_sys_cpu_gccgo_lo)
+	$(golangorg_x_sys_cpu_gccgo_x86_lo)
 
 libgo_ldflags = \
 	-version-info $(libtool_VERSION) $(PTHREAD_CFLAGS) $(AM_LDFLAGS)
@@ -1008,6 +1014,7 @@
 extra_check_libs_cmd_go_internal_module = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_go_internal_mvs = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_go_internal_search = $(abs_builddir)/libgotool.a
+extra_check_libs_cmd_go_internal_test = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_go_internal_web2 = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_go_internal_work = $(abs_builddir)/libgotool.a
 
@@ -1060,9 +1067,9 @@
 	$(LTCOMPILE) -c -o $@ $(srcdir)/go/internal/cpu/cpu_gccgo.c
 
 # Similarly, golang.org/x/sys/cpu needs some C code.
-golang.org/x/sys/cpu_gccgo.lo: go/golang.org/x/sys/cpu/cpu_gccgo.c runtime.inc
+golang.org/x/sys/cpu_gccgo_x86.lo: go/golang.org/x/sys/cpu/cpu_gccgo_x86.c runtime.inc
 	@$(MKDIR_P) golang.org/x/sys
-	$(LTCOMPILE) -c -o $@ $(srcdir)/go/golang.org/x/sys/cpu/cpu_gccgo.c
+	$(LTCOMPILE) -c -o $@ $(srcdir)/go/golang.org/x/sys/cpu/cpu_gccgo_x86.c
 
 # Solaris 11.4 changed the type of fields in struct stat.
 # Use a build tag, based on a configure check, to cope.
@@ -1238,7 +1245,7 @@
 
 MAJOR=$(firstword $(subst :, ,$(libtool_VERSION)))
 add-aix-fat-library: all-multi
-    @if test "$(MULTIBUILDTOP)" = ""; then \
-        ${AR} -X$(AIX_DEFAULT_ARCH) rc .libs/$(PACKAGE).a ../ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \
-        ${AR} -X$(AIX_DEFAULT_ARCH) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \
-    fi
+	@if test "$(MULTIBUILDTOP)" = ""; then \
+	  ${AR} -X$(AIX_DEFAULT_ARCH) rc .libs/$(PACKAGE).a ../ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \
+	  ${AR} -X$(AIX_DEFAULT_ARCH) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \
+	fi
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 5cb4484..4aa9e98 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -191,6 +191,7 @@
 	"$(DESTDIR)$(toolexeclibgotestinginternaldir)" \
 	"$(DESTDIR)$(toolexeclibgotextdir)" \
 	"$(DESTDIR)$(toolexeclibgotexttemplatedir)" \
+	"$(DESTDIR)$(toolexeclibgotimedir)" \
 	"$(DESTDIR)$(toolexeclibgounicodedir)"
 LIBRARIES = $(noinst_LIBRARIES) $(toolexeclib_LIBRARIES)
 ARFLAGS = cru
@@ -218,7 +219,8 @@
 libgotool_a_OBJECTS = $(am_libgotool_a_OBJECTS)
 LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
 @LIBGO_IS_LINUX_TRUE@am__DEPENDENCIES_1 = syscall/clone_linux.lo
-@LIBGO_IS_X86_TRUE@am__DEPENDENCIES_2 = golang.org/x/sys/cpu_gccgo.lo
+@LIBGO_IS_X86_TRUE@am__DEPENDENCIES_2 =  \
+@LIBGO_IS_X86_TRUE@	golang.org/x/sys/cpu_gccgo_x86.lo
 am__DEPENDENCIES_3 = $(addsuffix .lo,$(PACKAGES)) \
 	internal/bytealg/bytealg.lo reflect/makefunc_ffi_c.lo \
 	$(am__DEPENDENCIES_1) syscall/errno.lo syscall/signame.lo \
@@ -345,7 +347,8 @@
 	$(toolexeclibgoruntime_DATA) $(toolexeclibgosync_DATA) \
 	$(toolexeclibgotesting_DATA) \
 	$(toolexeclibgotestinginternal_DATA) $(toolexeclibgotext_DATA) \
-	$(toolexeclibgotexttemplate_DATA) $(toolexeclibgounicode_DATA)
+	$(toolexeclibgotexttemplate_DATA) $(toolexeclibgotime_DATA) \
+	$(toolexeclibgounicode_DATA)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
   distclean-recursive maintainer-clean-recursive
 am__recursive_targets = \
@@ -856,6 +859,10 @@
 toolexeclibgotexttemplate_DATA = \
 	text/template/parse.gox
 
+toolexeclibgotimedir = $(toolexeclibgodir)/time
+toolexeclibgotime_DATA = \
+	time/tzdata.gox
+
 toolexeclibgounicodedir = $(toolexeclibgodir)/unicode
 toolexeclibgounicode_DATA = \
 	unicode/utf16.gox \
@@ -865,16 +872,17 @@
 # Some internal packages are needed to bootstrap the gc toolchain.
 toolexeclibgointernaldir = $(toolexeclibgodir)/internal
 toolexeclibgointernal_DATA = \
-	internal/reflectlite.gox
+	internal/reflectlite.gox \
+	internal/unsafeheader.gox
 
 
 # Some packages are only needed for tests, so unlike the other
 # internal packages nothing will explicitly depend on them.
 # Force them to be built.
 noinst_DATA = golang.org/x/net/nettest.gox internal/cfg.gox \
-	internal/obscuretestdata.gox internal/testenv.gox \
-	internal/trace.gox net/internal/socktest.gox \
-	os/signal/internal/pty.gox runtime/pprof/internal/profile.gox \
+	internal/obscuretestdata.gox internal/profile.gox \
+	internal/testenv.gox internal/trace.gox \
+	net/internal/socktest.gox os/signal/internal/pty.gox \
 	zdefaultcc.go
 @LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file = 
 @LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c
@@ -923,8 +931,8 @@
 
 @LIBGO_IS_LINUX_FALSE@syscall_lib_clone_lo = 
 @LIBGO_IS_LINUX_TRUE@syscall_lib_clone_lo = syscall/clone_linux.lo
-@LIBGO_IS_X86_FALSE@golangorg_x_sys_cpu_gccgo_lo = 
-@LIBGO_IS_X86_TRUE@golangorg_x_sys_cpu_gccgo_lo = golang.org/x/sys/cpu_gccgo.lo
+@LIBGO_IS_X86_FALSE@golangorg_x_sys_cpu_gccgo_x86_lo = 
+@LIBGO_IS_X86_TRUE@golangorg_x_sys_cpu_gccgo_x86_lo = golang.org/x/sys/cpu_gccgo_x86.lo
 PACKAGES = $(shell cat $(srcdir)/libgo-packages.txt)
 libgo_go_objs = \
 	$(addsuffix .lo,$(PACKAGES)) \
@@ -941,7 +949,7 @@
 	runtime/internal/atomic_c.lo \
 	sync/atomic_c.lo \
 	internal/cpu/cpu_gccgo.lo \
-	$(golangorg_x_sys_cpu_gccgo_lo)
+	$(golangorg_x_sys_cpu_gccgo_x86_lo)
 
 libgo_ldflags = \
 	-version-info $(libtool_VERSION) $(PTHREAD_CFLAGS) $(AM_LDFLAGS)
@@ -1130,6 +1138,7 @@
 extra_check_libs_cmd_go_internal_module = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_go_internal_mvs = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_go_internal_search = $(abs_builddir)/libgotool.a
+extra_check_libs_cmd_go_internal_test = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_go_internal_web2 = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_go_internal_work = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_vet_internal_cfg = $(abs_builddir)/libgotool.a
@@ -2223,6 +2232,27 @@
 	@list='$(toolexeclibgotexttemplate_DATA)'; test -n "$(toolexeclibgotexttemplatedir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
 	dir='$(DESTDIR)$(toolexeclibgotexttemplatedir)'; $(am__uninstall_files_from_dir)
+install-toolexeclibgotimeDATA: $(toolexeclibgotime_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(toolexeclibgotime_DATA)'; test -n "$(toolexeclibgotimedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibgotimedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(toolexeclibgotimedir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(toolexeclibgotimedir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(toolexeclibgotimedir)" || exit $$?; \
+	done
+
+uninstall-toolexeclibgotimeDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(toolexeclibgotime_DATA)'; test -n "$(toolexeclibgotimedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(toolexeclibgotimedir)'; $(am__uninstall_files_from_dir)
 install-toolexeclibgounicodeDATA: $(toolexeclibgounicode_DATA)
 	@$(NORMAL_INSTALL)
 	@list='$(toolexeclibgounicode_DATA)'; test -n "$(toolexeclibgounicodedir)" || list=; \
@@ -2356,7 +2386,7 @@
 		all-local
 installdirs: installdirs-recursive
 installdirs-am:
-	for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibgodir)" "$(DESTDIR)$(toolexeclibgoarchivedir)" "$(DESTDIR)$(toolexeclibgocompressdir)" "$(DESTDIR)$(toolexeclibgocontainerdir)" "$(DESTDIR)$(toolexeclibgocryptodir)" "$(DESTDIR)$(toolexeclibgocryptox509dir)" "$(DESTDIR)$(toolexeclibgodatabasedir)" "$(DESTDIR)$(toolexeclibgodatabasesqldir)" "$(DESTDIR)$(toolexeclibgodebugdir)" "$(DESTDIR)$(toolexeclibgoencodingdir)" "$(DESTDIR)$(toolexeclibgogodir)" "$(DESTDIR)$(toolexeclibgohashdir)" "$(DESTDIR)$(toolexeclibgohtmldir)" "$(DESTDIR)$(toolexeclibgoimagedir)" "$(DESTDIR)$(toolexeclibgoimagecolordir)" "$(DESTDIR)$(toolexeclibgoindexdir)" "$(DESTDIR)$(toolexeclibgointernaldir)" "$(DESTDIR)$(toolexeclibgoiodir)" "$(DESTDIR)$(toolexeclibgologdir)" "$(DESTDIR)$(toolexeclibgomathdir)" "$(DESTDIR)$(toolexeclibgomimedir)" "$(DESTDIR)$(toolexeclibgonetdir)" "$(DESTDIR)$(toolexeclibgonethttpdir)" "$(DESTDIR)$(toolexeclibgonetrpcdir)" "$(DESTDIR)$(toolexeclibgoosdir)" "$(DESTDIR)$(toolexeclibgopathdir)" "$(DESTDIR)$(toolexeclibgoregexpdir)" "$(DESTDIR)$(toolexeclibgoruntimedir)" "$(DESTDIR)$(toolexeclibgosyncdir)" "$(DESTDIR)$(toolexeclibgotestingdir)" "$(DESTDIR)$(toolexeclibgotestinginternaldir)" "$(DESTDIR)$(toolexeclibgotextdir)" "$(DESTDIR)$(toolexeclibgotexttemplatedir)" "$(DESTDIR)$(toolexeclibgounicodedir)"; do \
+	for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibgodir)" "$(DESTDIR)$(toolexeclibgoarchivedir)" "$(DESTDIR)$(toolexeclibgocompressdir)" "$(DESTDIR)$(toolexeclibgocontainerdir)" "$(DESTDIR)$(toolexeclibgocryptodir)" "$(DESTDIR)$(toolexeclibgocryptox509dir)" "$(DESTDIR)$(toolexeclibgodatabasedir)" "$(DESTDIR)$(toolexeclibgodatabasesqldir)" "$(DESTDIR)$(toolexeclibgodebugdir)" "$(DESTDIR)$(toolexeclibgoencodingdir)" "$(DESTDIR)$(toolexeclibgogodir)" "$(DESTDIR)$(toolexeclibgohashdir)" "$(DESTDIR)$(toolexeclibgohtmldir)" "$(DESTDIR)$(toolexeclibgoimagedir)" "$(DESTDIR)$(toolexeclibgoimagecolordir)" "$(DESTDIR)$(toolexeclibgoindexdir)" "$(DESTDIR)$(toolexeclibgointernaldir)" "$(DESTDIR)$(toolexeclibgoiodir)" "$(DESTDIR)$(toolexeclibgologdir)" "$(DESTDIR)$(toolexeclibgomathdir)" "$(DESTDIR)$(toolexeclibgomimedir)" "$(DESTDIR)$(toolexeclibgonetdir)" "$(DESTDIR)$(toolexeclibgonethttpdir)" "$(DESTDIR)$(toolexeclibgonetrpcdir)" "$(DESTDIR)$(toolexeclibgoosdir)" "$(DESTDIR)$(toolexeclibgopathdir)" "$(DESTDIR)$(toolexeclibgoregexpdir)" "$(DESTDIR)$(toolexeclibgoruntimedir)" "$(DESTDIR)$(toolexeclibgosyncdir)" "$(DESTDIR)$(toolexeclibgotestingdir)" "$(DESTDIR)$(toolexeclibgotestinginternaldir)" "$(DESTDIR)$(toolexeclibgotextdir)" "$(DESTDIR)$(toolexeclibgotexttemplatedir)" "$(DESTDIR)$(toolexeclibgotimedir)" "$(DESTDIR)$(toolexeclibgounicodedir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-recursive
@@ -2450,7 +2480,7 @@
 	install-toolexeclibgotestinginternalDATA \
 	install-toolexeclibgotextDATA \
 	install-toolexeclibgotexttemplateDATA \
-	install-toolexeclibgounicodeDATA
+	install-toolexeclibgotimeDATA install-toolexeclibgounicodeDATA
 
 install-html: install-html-recursive
 
@@ -2523,6 +2553,7 @@
 	uninstall-toolexeclibgotestinginternalDATA \
 	uninstall-toolexeclibgotextDATA \
 	uninstall-toolexeclibgotexttemplateDATA \
+	uninstall-toolexeclibgotimeDATA \
 	uninstall-toolexeclibgounicodeDATA
 
 .MAKE: $(am__recursive_targets) all install-am install-strip
@@ -2564,12 +2595,13 @@
 	install-toolexeclibgotestinginternalDATA \
 	install-toolexeclibgotextDATA \
 	install-toolexeclibgotexttemplateDATA \
-	install-toolexeclibgounicodeDATA installcheck installcheck-am \
-	installdirs installdirs-am maintainer-clean \
-	maintainer-clean-generic maintainer-clean-local mostlyclean \
-	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-	mostlyclean-local pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am uninstall-toolexeclibLIBRARIES \
+	install-toolexeclibgotimeDATA install-toolexeclibgounicodeDATA \
+	installcheck installcheck-am installdirs installdirs-am \
+	maintainer-clean maintainer-clean-generic \
+	maintainer-clean-local mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool mostlyclean-local pdf \
+	pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-toolexeclibLIBRARIES \
 	uninstall-toolexeclibLTLIBRARIES uninstall-toolexeclibgoDATA \
 	uninstall-toolexeclibgoarchiveDATA \
 	uninstall-toolexeclibgocompressDATA \
@@ -2599,6 +2631,7 @@
 	uninstall-toolexeclibgotestinginternalDATA \
 	uninstall-toolexeclibgotextDATA \
 	uninstall-toolexeclibgotexttemplateDATA \
+	uninstall-toolexeclibgotimeDATA \
 	uninstall-toolexeclibgounicodeDATA
 
 .PRECIOUS: Makefile
@@ -2929,9 +2962,9 @@
 	$(LTCOMPILE) -c -o $@ $(srcdir)/go/internal/cpu/cpu_gccgo.c
 
 # Similarly, golang.org/x/sys/cpu needs some C code.
-golang.org/x/sys/cpu_gccgo.lo: go/golang.org/x/sys/cpu/cpu_gccgo.c runtime.inc
+golang.org/x/sys/cpu_gccgo_x86.lo: go/golang.org/x/sys/cpu/cpu_gccgo_x86.c runtime.inc
 	@$(MKDIR_P) golang.org/x/sys
-	$(LTCOMPILE) -c -o $@ $(srcdir)/go/golang.org/x/sys/cpu/cpu_gccgo.c
+	$(LTCOMPILE) -c -o $@ $(srcdir)/go/golang.org/x/sys/cpu/cpu_gccgo_x86.c
 
 # Build golang.org/x/net/route only on BSD systems.
 
@@ -3087,8 +3120,8 @@
 all-local: $(ALL_LOCAL_DEPS)
 add-aix-fat-library: all-multi
 	@if test "$(MULTIBUILDTOP)" = ""; then \
-		${AR} -X$(AIX_DEFAULT_ARCH) rc .libs/$(PACKAGE).a ../ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \
-		${AR} -X$(AIX_DEFAULT_ARCH) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \
+	  ${AR} -X$(AIX_DEFAULT_ARCH) rc .libs/$(PACKAGE).a ../ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \
+	  ${AR} -X$(AIX_DEFAULT_ARCH) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(AIX_DEFAULT_ARCH)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR); \
 	fi
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/libgo/VERSION b/libgo/VERSION
index 398d253..0bcf07d 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.14.6
+go1.15rc1
diff --git a/libgo/check-packages.txt b/libgo/check-packages.txt
index 48c4dfd..efa7d19 100644
--- a/libgo/check-packages.txt
+++ b/libgo/check-packages.txt
@@ -16,6 +16,7 @@
 cmd/go/internal/mvs
 cmd/go/internal/par
 cmd/go/internal/search
+cmd/go/internal/test
 cmd/go/internal/txtar
 cmd/go/internal/work
 cmd/internal/buildid
@@ -104,9 +105,11 @@
 internal/cpu
 internal/fmtsort
 internal/poll
+internal/profile
 internal/reflectlite
 internal/singleflight
 internal/trace
+internal/unsafeheader
 internal/xcoff
 io
 io/ioutil
@@ -152,7 +155,6 @@
 runtime/internal/math
 runtime/internal/sys
 runtime/pprof
-runtime/pprof/internal/profile
 runtime/trace
 sort
 strconv
diff --git a/libgo/configure b/libgo/configure
index 67470ac..74bf072 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -2551,7 +2551,7 @@
 ac_config_headers="$ac_config_headers config.h"
 
 
-libtool_VERSION=16:0:0
+libtool_VERSION=17:0:0
 
 
 # Default to --enable-multilib
@@ -11501,7 +11501,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11602 "configure"
+#line 11504 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11607,7 +11607,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11708 "configure"
+#line 11610 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
diff --git a/libgo/configure.ac b/libgo/configure.ac
index 841cba1..db5848e 100644
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -10,7 +10,7 @@
 AC_CONFIG_SRCDIR(Makefile.am)
 AC_CONFIG_HEADER(config.h)
 
-libtool_VERSION=16:0:0
+libtool_VERSION=17:0:0
 AC_SUBST(libtool_VERSION)
 
 AM_ENABLE_MULTILIB(, ..)
diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go
index f0810be..7cbd542 100644
--- a/libgo/go/bufio/bufio.go
+++ b/libgo/go/bufio/bufio.go
@@ -11,6 +11,7 @@
 	"bytes"
 	"errors"
 	"io"
+	"strings"
 	"unicode/utf8"
 )
 
@@ -419,20 +420,16 @@
 	return
 }
 
-// ReadBytes reads until the first occurrence of delim in the input,
-// returning a slice containing the data up to and including the delimiter.
-// If ReadBytes encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadBytes returns err != nil if and only if the returned data does not end in
-// delim.
-// For simple uses, a Scanner may be more convenient.
-func (b *Reader) ReadBytes(delim byte) ([]byte, error) {
-	// Use ReadSlice to look for array,
-	// accumulating full buffers.
+// collectFragments reads until the first occurrence of delim in the input. It
+// returns (slice of full buffers, remaining bytes before delim, total number
+// of bytes in the combined first two elements, error).
+// The complete result is equal to
+// `bytes.Join(append(fullBuffers, finalFragment), nil)`, which has a
+// length of `totalLen`. The result is strucured in this way to allow callers
+// to minimize allocations and copies.
+func (b *Reader) collectFragments(delim byte) (fullBuffers [][]byte, finalFragment []byte, totalLen int, err error) {
 	var frag []byte
-	var full [][]byte
-	var err error
-	n := 0
+	// Use ReadSlice to look for delim, accumulating full buffers.
 	for {
 		var e error
 		frag, e = b.ReadSlice(delim)
@@ -447,12 +444,23 @@
 		// Make a copy of the buffer.
 		buf := make([]byte, len(frag))
 		copy(buf, frag)
-		full = append(full, buf)
-		n += len(buf)
+		fullBuffers = append(fullBuffers, buf)
+		totalLen += len(buf)
 	}
 
-	n += len(frag)
+	totalLen += len(frag)
+	return fullBuffers, frag, totalLen, err
+}
 
+// ReadBytes reads until the first occurrence of delim in the input,
+// returning a slice containing the data up to and including the delimiter.
+// If ReadBytes encounters an error before finding a delimiter,
+// it returns the data read before the error and the error itself (often io.EOF).
+// ReadBytes returns err != nil if and only if the returned data does not end in
+// delim.
+// For simple uses, a Scanner may be more convenient.
+func (b *Reader) ReadBytes(delim byte) ([]byte, error) {
+	full, frag, n, err := b.collectFragments(delim)
 	// Allocate new buffer to hold the full pieces and the fragment.
 	buf := make([]byte, n)
 	n = 0
@@ -472,8 +480,16 @@
 // delim.
 // For simple uses, a Scanner may be more convenient.
 func (b *Reader) ReadString(delim byte) (string, error) {
-	bytes, err := b.ReadBytes(delim)
-	return string(bytes), err
+	full, frag, n, err := b.collectFragments(delim)
+	// Allocate new buffer to hold the full pieces and the fragment.
+	var buf strings.Builder
+	buf.Grow(n)
+	// Copy full pieces and fragment in.
+	for _, fb := range full {
+		buf.Write(fb)
+	}
+	buf.Write(frag)
+	return buf.String(), err
 }
 
 // WriteTo implements io.WriterTo.
diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go
index 9a9f102..cb68f3b 100644
--- a/libgo/go/bufio/bufio_test.go
+++ b/libgo/go/bufio/bufio_test.go
@@ -147,7 +147,7 @@
 	for i := 0; i < len(texts)-1; i++ {
 		texts[i] = str + "\n"
 		all += texts[i]
-		str += string(i%26 + 'a')
+		str += string(rune(i)%26 + 'a')
 	}
 	texts[len(texts)-1] = all
 
@@ -535,6 +535,23 @@
 	}
 }
 
+func TestReadStringAllocs(t *testing.T) {
+	r := strings.NewReader("       foo       foo        42        42        42        42        42        42        42        42       4.2       4.2       4.2       4.2\n")
+	buf := NewReader(r)
+	allocs := testing.AllocsPerRun(100, func() {
+		r.Seek(0, io.SeekStart)
+		buf.Reset(r)
+
+		_, err := buf.ReadString('\n')
+		if err != nil {
+			t.Fatal(err)
+		}
+	})
+	if allocs != 1 {
+		t.Errorf("Unexpected number of allocations, got %f, want 1", allocs)
+	}
+}
+
 func TestWriter(t *testing.T) {
 	var data [8192]byte
 
@@ -1644,6 +1661,21 @@
 	}
 }
 
+func BenchmarkReaderReadString(b *testing.B) {
+	r := strings.NewReader("       foo       foo        42        42        42        42        42        42        42        42       4.2       4.2       4.2       4.2\n")
+	buf := NewReader(r)
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		r.Seek(0, io.SeekStart)
+		buf.Reset(r)
+
+		_, err := buf.ReadString('\n')
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
 func BenchmarkWriterCopyOptimal(b *testing.B) {
 	// Optimal case is where the underlying writer implements io.ReaderFrom
 	srcBuf := bytes.NewBuffer(make([]byte, 8192))
diff --git a/libgo/go/bufio/scan.go b/libgo/go/bufio/scan.go
index 4e787c4..af46a14 100644
--- a/libgo/go/bufio/scan.go
+++ b/libgo/go/bufio/scan.go
@@ -69,6 +69,7 @@
 	ErrTooLong         = errors.New("bufio.Scanner: token too long")
 	ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
 	ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
+	ErrBadReadCount    = errors.New("bufio.Scanner: Read returned impossible count")
 )
 
 const (
@@ -211,6 +212,10 @@
 		// be extra careful: Scanner is for safe, simple jobs.
 		for loop := 0; ; {
 			n, err := s.r.Read(s.buf[s.end:len(s.buf)])
+			if n < 0 || len(s.buf)-s.end < n {
+				s.setErr(ErrBadReadCount)
+				break
+			}
 			s.end += n
 			if err != nil {
 				s.setErr(err)
diff --git a/libgo/go/bufio/scan_test.go b/libgo/go/bufio/scan_test.go
index 2568225..e99b09f 100644
--- a/libgo/go/bufio/scan_test.go
+++ b/libgo/go/bufio/scan_test.go
@@ -537,3 +537,60 @@
 		t.Fatal("after scan:", s.Err())
 	}
 }
+
+// negativeEOFReader returns an invalid -1 at the end, as though it
+// were wrapping the read system call.
+type negativeEOFReader int
+
+func (r *negativeEOFReader) Read(p []byte) (int, error) {
+	if *r > 0 {
+		c := int(*r)
+		if c > len(p) {
+			c = len(p)
+		}
+		for i := 0; i < c; i++ {
+			p[i] = 'a'
+		}
+		p[c-1] = '\n'
+		*r -= negativeEOFReader(c)
+		return c, nil
+	}
+	return -1, io.EOF
+}
+
+// Test that the scanner doesn't panic and returns ErrBadReadCount
+// on a reader that returns a negative count of bytes read (issue 38053).
+func TestNegativeEOFReader(t *testing.T) {
+	r := negativeEOFReader(10)
+	scanner := NewScanner(&r)
+	c := 0
+	for scanner.Scan() {
+		c++
+		if c > 1 {
+			t.Error("read too many lines")
+			break
+		}
+	}
+	if got, want := scanner.Err(), ErrBadReadCount; got != want {
+		t.Errorf("scanner.Err: got %v, want %v", got, want)
+	}
+}
+
+// largeReader returns an invalid count that is larger than the number
+// of bytes requested.
+type largeReader struct{}
+
+func (largeReader) Read(p []byte) (int, error) {
+	return len(p) + 1, nil
+}
+
+// Test that the scanner doesn't panic and returns ErrBadReadCount
+// on a reader that returns an impossibly large count of bytes read (issue 38053).
+func TestLargeReader(t *testing.T) {
+	scanner := NewScanner(largeReader{})
+	for scanner.Scan() {
+	}
+	if got, want := scanner.Err(), ErrBadReadCount; got != want {
+		t.Errorf("scanner.Err: got %v, want %v", got, want)
+	}
+}
diff --git a/libgo/go/bytes/buffer_test.go b/libgo/go/bytes/buffer_test.go
index 7626d27..fec5ef8 100644
--- a/libgo/go/bytes/buffer_test.go
+++ b/libgo/go/bytes/buffer_test.go
@@ -8,7 +8,6 @@
 	. "bytes"
 	"io"
 	"math/rand"
-	"runtime"
 	"testing"
 	"unicode/utf8"
 )
@@ -495,20 +494,20 @@
 	x := []byte{'x'}
 	y := []byte{'y'}
 	tmp := make([]byte, 72)
-	for _, startLen := range []int{0, 100, 1000, 10000, 100000} {
-		xBytes := Repeat(x, startLen)
-		for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
+	for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
+		for _, startLen := range []int{0, 100, 1000, 10000, 100000} {
+			xBytes := Repeat(x, startLen)
+
 			buf := NewBuffer(xBytes)
 			// If we read, this affects buf.off, which is good to test.
 			readBytes, _ := buf.Read(tmp)
-			buf.Grow(growLen)
 			yBytes := Repeat(y, growLen)
+			allocs := testing.AllocsPerRun(100, func() {
+				buf.Grow(growLen)
+				buf.Write(yBytes)
+			})
 			// Check no allocation occurs in write, as long as we're single-threaded.
-			var m1, m2 runtime.MemStats
-			runtime.ReadMemStats(&m1)
-			buf.Write(yBytes)
-			runtime.ReadMemStats(&m2)
-			if runtime.GOMAXPROCS(-1) == 1 && m1.Mallocs != m2.Mallocs {
+			if allocs != 0 {
 				t.Errorf("allocation occurred during write")
 			}
 			// Check that buffer has correct data.
diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go
index e872cc2..aa07b9f 100644
--- a/libgo/go/bytes/bytes.go
+++ b/libgo/go/bytes/bytes.go
@@ -117,17 +117,17 @@
 		return -1
 	}
 	// Rabin-Karp search from the end of the string
-	hashss, pow := hashStrRev(sep)
+	hashss, pow := bytealg.HashStrRevBytes(sep)
 	last := len(s) - n
 	var h uint32
 	for i := len(s) - 1; i >= last; i-- {
-		h = h*primeRK + uint32(s[i])
+		h = h*bytealg.PrimeRK + uint32(s[i])
 	}
 	if h == hashss && Equal(s[last:], sep) {
 		return last
 	}
 	for i := last - 1; i >= 0; i-- {
-		h *= primeRK
+		h *= bytealg.PrimeRK
 		h += uint32(s[i])
 		h -= pow * uint32(s[i+n])
 		if h == hashss && Equal(s[i:i+n], sep) {
@@ -183,6 +183,29 @@
 		// Avoid scanning all of s.
 		return -1
 	}
+	if len(s) == 1 {
+		r := rune(s[0])
+		if r >= utf8.RuneSelf {
+			// search utf8.RuneError.
+			for _, r = range chars {
+				if r == utf8.RuneError {
+					return 0
+				}
+			}
+			return -1
+		}
+		if bytealg.IndexByteString(chars, s[0]) >= 0 {
+			return 0
+		}
+		return -1
+	}
+	if len(chars) == 1 {
+		r := rune(chars[0])
+		if r >= utf8.RuneSelf {
+			r = utf8.RuneError
+		}
+		return IndexRune(s, r)
+	}
 	if len(s) > 8 {
 		if as, isASCII := makeASCIISet(chars); isASCII {
 			for i, c := range s {
@@ -197,14 +220,26 @@
 	for i := 0; i < len(s); i += width {
 		r := rune(s[i])
 		if r < utf8.RuneSelf {
-			width = 1
-		} else {
-			r, width = utf8.DecodeRune(s[i:])
-		}
-		for _, ch := range chars {
-			if r == ch {
+			if bytealg.IndexByteString(chars, s[i]) >= 0 {
 				return i
 			}
+			width = 1
+			continue
+		}
+		r, width = utf8.DecodeRune(s[i:])
+		if r == utf8.RuneError {
+			for _, r = range chars {
+				if r == utf8.RuneError {
+					return i
+				}
+			}
+			continue
+		}
+		// r is 2 to 4 bytes. Using strings.Index is more reasonable, but as the bytes
+		// package should not import the strings package, use bytealg.IndexString
+		// instead. And this does not seem to lose much performance.
+		if chars == string(r) || bytealg.IndexString(chars, string(r)) >= 0 {
+			return i
 		}
 	}
 	return -1
@@ -229,14 +264,60 @@
 			return -1
 		}
 	}
-	for i := len(s); i > 0; {
-		r, size := utf8.DecodeLastRune(s[:i])
-		i -= size
-		for _, c := range chars {
-			if r == c {
+	if len(s) == 1 {
+		r := rune(s[0])
+		if r >= utf8.RuneSelf {
+			for _, r = range chars {
+				if r == utf8.RuneError {
+					return 0
+				}
+			}
+			return -1
+		}
+		if bytealg.IndexByteString(chars, s[0]) >= 0 {
+			return 0
+		}
+		return -1
+	}
+	if len(chars) == 1 {
+		cr := rune(chars[0])
+		if cr >= utf8.RuneSelf {
+			cr = utf8.RuneError
+		}
+		for i := len(s); i > 0; {
+			r, size := utf8.DecodeLastRune(s[:i])
+			i -= size
+			if r == cr {
 				return i
 			}
 		}
+		return -1
+	}
+	for i := len(s); i > 0; {
+		r := rune(s[i-1])
+		if r < utf8.RuneSelf {
+			if bytealg.IndexByteString(chars, s[i-1]) >= 0 {
+				return i - 1
+			}
+			i--
+			continue
+		}
+		r, size := utf8.DecodeLastRune(s[:i])
+		i -= size
+		if r == utf8.RuneError {
+			for _, r = range chars {
+				if r == utf8.RuneError {
+					return i
+				}
+			}
+			continue
+		}
+		// r is 2 to 4 bytes. Using strings.Index is more reasonable, but as the bytes
+		// package should not import the strings package, use bytealg.IndexString
+		// instead. And this does not seem to lose much performance.
+		if chars == string(r) || bytealg.IndexString(chars, string(r)) >= 0 {
+			return i
+		}
 	}
 	return -1
 }
@@ -364,8 +445,9 @@
 // It splits the slice s at each run of code points c satisfying f(c) and
 // returns a slice of subslices of s. If all code points in s satisfy f(c), or
 // len(s) == 0, an empty slice is returned.
-// FieldsFunc makes no guarantees about the order in which it calls f(c).
-// If f does not return consistent results for a given c, FieldsFunc may crash.
+//
+// FieldsFunc makes no guarantees about the order in which it calls f(c)
+// and assumes that f always returns the same value for a given c.
 func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
 	// A span is used to record a slice of s of the form s[start:end].
 	// The start index is inclusive and the end index is exclusive.
@@ -376,8 +458,10 @@
 	spans := make([]span, 0, 32)
 
 	// Find the field start and end indices.
-	wasField := false
-	fromIndex := 0
+	// Doing this in a separate pass (rather than slicing the string s
+	// and collecting the result substrings right away) is significantly
+	// more efficient, possibly due to cache effects.
+	start := -1 // valid span start if >= 0
 	for i := 0; i < len(s); {
 		size := 1
 		r := rune(s[i])
@@ -385,22 +469,21 @@
 			r, size = utf8.DecodeRune(s[i:])
 		}
 		if f(r) {
-			if wasField {
-				spans = append(spans, span{start: fromIndex, end: i})
-				wasField = false
+			if start >= 0 {
+				spans = append(spans, span{start, i})
+				start = -1
 			}
 		} else {
-			if !wasField {
-				fromIndex = i
-				wasField = true
+			if start < 0 {
+				start = i
 			}
 		}
 		i += size
 	}
 
 	// Last field might end at EOF.
-	if wasField {
-		spans = append(spans, span{fromIndex, len(s)})
+	if start >= 0 {
+		spans = append(spans, span{start, len(s)})
 	}
 
 	// Create subslices from recorded field indices.
@@ -1019,11 +1102,11 @@
 			if s[i] != c0 {
 				// IndexByte is faster than bytealg.Index, so use it as long as
 				// we're not getting lots of false positives.
-				o := IndexByte(s[i:t], c0)
+				o := IndexByte(s[i+1:t], c0)
 				if o < 0 {
 					return -1
 				}
-				i += o
+				i += o + 1
 			}
 			if s[i+1] == c1 && Equal(s[i:i+n], sep) {
 				return i
@@ -1048,11 +1131,11 @@
 	t := len(s) - n + 1
 	for i < t {
 		if s[i] != c0 {
-			o := IndexByte(s[i:t], c0)
+			o := IndexByte(s[i+1:t], c0)
 			if o < 0 {
 				break
 			}
-			i += o
+			i += o + 1
 		}
 		if s[i+1] == c1 && Equal(s[i:i+n], sep) {
 			return i
@@ -1068,7 +1151,7 @@
 			// we should cutover at even larger average skips,
 			// because Equal becomes that much more expensive.
 			// This code does not take that effect into account.
-			j := indexRabinKarp(s[i:], sep)
+			j := bytealg.IndexRabinKarpBytes(s[i:], sep)
 			if j < 0 {
 				return -1
 			}
@@ -1077,63 +1160,3 @@
 	}
 	return -1
 }
-
-func indexRabinKarp(s, sep []byte) int {
-	// Rabin-Karp search
-	hashsep, pow := hashStr(sep)
-	n := len(sep)
-	var h uint32
-	for i := 0; i < n; i++ {
-		h = h*primeRK + uint32(s[i])
-	}
-	if h == hashsep && Equal(s[:n], sep) {
-		return 0
-	}
-	for i := n; i < len(s); {
-		h *= primeRK
-		h += uint32(s[i])
-		h -= pow * uint32(s[i-n])
-		i++
-		if h == hashsep && Equal(s[i-n:i], sep) {
-			return i - n
-		}
-	}
-	return -1
-}
-
-// primeRK is the prime base used in Rabin-Karp algorithm.
-const primeRK = 16777619
-
-// hashStr returns the hash and the appropriate multiplicative
-// factor for use in Rabin-Karp algorithm.
-func hashStr(sep []byte) (uint32, uint32) {
-	hash := uint32(0)
-	for i := 0; i < len(sep); i++ {
-		hash = hash*primeRK + uint32(sep[i])
-	}
-	var pow, sq uint32 = 1, primeRK
-	for i := len(sep); i > 0; i >>= 1 {
-		if i&1 != 0 {
-			pow *= sq
-		}
-		sq *= sq
-	}
-	return hash, pow
-}
-
-// hashStrRev returns the hash of the reverse of sep and the
-// appropriate multiplicative factor for use in Rabin-Karp algorithm.
-func hashStrRev(sep []byte) (uint32, uint32) {
-	hash := uint32(0)
-	for i := len(sep) - 1; i >= 0; i-- {
-		hash = hash*primeRK + uint32(sep[i])
-	}
-	var pow, sq uint32 = 1, primeRK
-	for i := len(sep); i > 0; i >>= 1 {
-		if i&1 != 0 {
-			pow *= sq
-		}
-		sq *= sq
-	}
-	return hash, pow
-}
diff --git a/libgo/go/bytes/bytes_test.go b/libgo/go/bytes/bytes_test.go
index ebff5f0..0111d31 100644
--- a/libgo/go/bytes/bytes_test.go
+++ b/libgo/go/bytes/bytes_test.go
@@ -142,9 +142,10 @@
 	{"barfoobarfooyyyzzzyyyzzzyyyzzzyyyxxxzzzyyy", "x", 33},
 	{"foofyfoobarfoobar", "y", 4},
 	{"oooooooooooooooooooooo", "r", -1},
-	// test fallback to Rabin-Karp.
 	{"oxoxoxoxoxoxoxoxoxoxoxoy", "oy", 22},
 	{"oxoxoxoxoxoxoxoxoxoxoxox", "oy", -1},
+	// test fallback to Rabin-Karp.
+	{"000000000000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000001", 5},
 }
 
 var lastIndexTests = []BinOpTest{
@@ -169,6 +170,7 @@
 	{"", "abc", -1},
 	{"a", "", -1},
 	{"a", "a", 0},
+	{"\x80", "\xffb", 0},
 	{"aaa", "a", 0},
 	{"abc", "xyz", -1},
 	{"abc", "xcz", 2},
@@ -179,6 +181,7 @@
 	{dots + dots + dots, " ", -1},
 	{"012abcba210", "\xffb", 4},
 	{"012\x80bcb\x80210", "\xffb", 3},
+	{"0123456\xcf\x80abc", "\xcfb\x80", 10},
 }
 
 var lastIndexAnyTests = []BinOpTest{
@@ -187,6 +190,7 @@
 	{"", "abc", -1},
 	{"a", "", -1},
 	{"a", "a", 0},
+	{"\x80", "\xffb", 0},
 	{"aaa", "a", 2},
 	{"abc", "xyz", -1},
 	{"abc", "ab", 1},
@@ -197,6 +201,7 @@
 	{dots + dots + dots, " ", -1},
 	{"012abcba210", "\xffb", 6},
 	{"012\x80bcb\x80210", "\xffb", 7},
+	{"0123456\xcf\x80abc", "\xcfb\x80", 10},
 }
 
 // Execute f on each test case.  funcName should be the name of f; it's used
@@ -210,6 +215,27 @@
 			t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, b, actual, test.i)
 		}
 	}
+	var allocTests = []struct {
+		a []byte
+		b []byte
+		i int
+	}{
+		// case for function Index.
+		{[]byte("000000000000000000000000000000000000000000000000000000000000000000000001"), []byte("0000000000000000000000000000000000000000000000000000000000000000001"), 5},
+		// case for function LastIndex.
+		{[]byte("000000000000000000000000000000000000000000000000000000000000000010000"), []byte("00000000000000000000000000000000000000000000000000000000000001"), 3},
+	}
+	allocs := testing.AllocsPerRun(100, func() {
+		if i := Index(allocTests[1].a, allocTests[1].b); i != allocTests[1].i {
+			t.Errorf("Index([]byte(%q), []byte(%q)) = %v; want %v", allocTests[1].a, allocTests[1].b, i, allocTests[1].i)
+		}
+		if i := LastIndex(allocTests[0].a, allocTests[0].b); i != allocTests[0].i {
+			t.Errorf("LastIndex([]byte(%q), []byte(%q)) = %v; want %v", allocTests[0].a, allocTests[0].b, i, allocTests[0].i)
+		}
+	})
+	if allocs != 0 {
+		t.Errorf("expected no allocations, got %f", allocs)
+	}
 }
 
 func runIndexAnyTests(t *testing.T, f func(s []byte, chars string) int, funcName string, testCases []BinOpTest) {
@@ -1873,10 +1899,10 @@
 }
 
 func BenchmarkIndexAnyASCII(b *testing.B) {
-	x := Repeat([]byte{'#'}, 4096) // Never matches set
-	cs := "0123456789abcdef"
-	for k := 1; k <= 4096; k <<= 4 {
-		for j := 1; j <= 16; j <<= 1 {
+	x := Repeat([]byte{'#'}, 2048) // Never matches set
+	cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
+	for k := 1; k <= 2048; k <<= 4 {
+		for j := 1; j <= 64; j <<= 1 {
 			b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
 				for i := 0; i < b.N; i++ {
 					IndexAny(x[:k], cs[:j])
@@ -1886,6 +1912,48 @@
 	}
 }
 
+func BenchmarkIndexAnyUTF8(b *testing.B) {
+	x := Repeat([]byte{'#'}, 2048) // Never matches set
+	cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world."
+	for k := 1; k <= 2048; k <<= 4 {
+		for j := 1; j <= 64; j <<= 1 {
+			b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
+				for i := 0; i < b.N; i++ {
+					IndexAny(x[:k], cs[:j])
+				}
+			})
+		}
+	}
+}
+
+func BenchmarkLastIndexAnyASCII(b *testing.B) {
+	x := Repeat([]byte{'#'}, 2048) // Never matches set
+	cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
+	for k := 1; k <= 2048; k <<= 4 {
+		for j := 1; j <= 64; j <<= 1 {
+			b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
+				for i := 0; i < b.N; i++ {
+					LastIndexAny(x[:k], cs[:j])
+				}
+			})
+		}
+	}
+}
+
+func BenchmarkLastIndexAnyUTF8(b *testing.B) {
+	x := Repeat([]byte{'#'}, 2048) // Never matches set
+	cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world."
+	for k := 1; k <= 2048; k <<= 4 {
+		for j := 1; j <= 64; j <<= 1 {
+			b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
+				for i := 0; i < b.N; i++ {
+					LastIndexAny(x[:k], cs[:j])
+				}
+			})
+		}
+	}
+}
+
 func BenchmarkTrimASCII(b *testing.B) {
 	cs := "0123456789abcdef"
 	for k := 1; k <= 4096; k <<= 4 {
diff --git a/libgo/go/cmd/cgo/doc.go b/libgo/go/cmd/cgo/doc.go
index 8c3bf81..ca18c45 100644
--- a/libgo/go/cmd/cgo/doc.go
+++ b/libgo/go/cmd/cgo/doc.go
@@ -413,7 +413,7 @@
 	jobjectArray
 	jweak
 
-3. The EGLDisplay type from the EGL API.
+3. The EGLDisplay and EGLConfig types from the EGL API.
 
 These types are uintptr on the Go side because they would otherwise
 confuse the Go garbage collector; they are sometimes not really
@@ -429,11 +429,16 @@
 
 It will replace nil with 0 in the appropriate places.
 
-The EGLDisplay case were introduced in Go 1.12. Use the egl rewrite
+The EGLDisplay case was introduced in Go 1.12. Use the egl rewrite
 to auto-update code from Go 1.11 and earlier:
 
 	go tool fix -r egl <pkg>
 
+The EGLConfig case was introduced in Go 1.15. Use the eglconf rewrite
+to auto-update code from Go 1.14 and earlier:
+
+	go tool fix -r eglconf <pkg>
+
 Using cgo directly
 
 Usage:
@@ -985,7 +990,7 @@
 linker in external linking mode.
 
 By default, cmd/link will decide the linking mode as follows: if the only
-packages using cgo are those on a whitelist of standard library
+packages using cgo are those on a list of known standard library
 packages (net, os/user, runtime/cgo), cmd/link will use internal linking
 mode. Otherwise, there are non-standard cgo packages involved, and cmd/link
 will use external linking mode. The first rule means that a build of
diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go
index e389729..249cfe4 100644
--- a/libgo/go/cmd/cgo/gcc.go
+++ b/libgo/go/cmd/cgo/gcc.go
@@ -200,6 +200,9 @@
 		numTypedefs = len(p.typedefs)
 		// Also ask about any typedefs we've seen so far.
 		for _, info := range p.typedefList {
+			if f.Name[info.typedef] != nil {
+				continue
+			}
 			n := &Name{
 				Go: info.typedef,
 				C:  info.typedef,
@@ -351,7 +354,7 @@
 	//	void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); }
 	//
 	// If we see an error at not-declared:xxx, the corresponding name is not declared.
-	// If we see an error at not-type:xxx, the corresponding name is a type.
+	// If we see an error at not-type:xxx, the corresponding name is not a type.
 	// If we see an error at not-int-const:xxx, the corresponding name is not an integer constant.
 	// If we see an error at not-num-const:xxx, the corresponding name is not a number constant.
 	// If we see an error at not-str-lit:xxx, the corresponding name is not a string literal.
@@ -728,6 +731,9 @@
 			}
 		}
 		p.mangleName(n)
+		if n.Kind == "type" && typedef[n.Mangle] == nil {
+			typedef[n.Mangle] = n.Type
+		}
 	}
 }
 
@@ -1366,6 +1372,9 @@
 
 		if *godefs {
 			// Substitute definition for mangled type name.
+			if r.Name.Type != nil && r.Name.Kind == "type" {
+				expr = r.Name.Type.Go
+			}
 			if id, ok := expr.(*ast.Ident); ok {
 				if t := typedef[id.Name]; t != nil {
 					expr = t.Go
@@ -1431,9 +1440,7 @@
 				r.Context = ctxType
 				if r.Name.Type == nil {
 					error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
-					break
 				}
-				expr = r.Name.Type.Go
 				break
 			}
 			error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
@@ -1490,9 +1497,7 @@
 			// Okay - might be new(T)
 			if r.Name.Type == nil {
 				error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
-				break
 			}
-			expr = r.Name.Type.Go
 		case "var":
 			expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
 		case "macro":
@@ -1511,8 +1516,6 @@
 			// Use of C.enum_x, C.struct_x or C.union_x without C definition.
 			// GCC won't raise an error when using pointers to such unknown types.
 			error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
-		} else {
-			expr = r.Name.Type.Go
 		}
 	default:
 		if r.Name.Kind == "func" {
@@ -3036,8 +3039,9 @@
 	return ok && st.StructName == ""
 }
 
-// badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go.
-// A typedef is bad if C code sometimes stores non-pointers in this type.
+// badPointerTypedef reports whether dt is a C typedef that should not be
+// considered a pointer in Go. A typedef is bad if C code sometimes stores
+// non-pointers in this type.
 // TODO: Currently our best solution is to find these manually and list them as
 // they come up. A better solution is desired.
 func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
@@ -3047,7 +3051,7 @@
 	if c.badJNI(dt) {
 		return true
 	}
-	if c.badEGLDisplay(dt) {
+	if c.badEGLType(dt) {
 		return true
 	}
 	return false
@@ -3186,11 +3190,11 @@
 	return false
 }
 
-func (c *typeConv) badEGLDisplay(dt *dwarf.TypedefType) bool {
-	if dt.Name != "EGLDisplay" {
+func (c *typeConv) badEGLType(dt *dwarf.TypedefType) bool {
+	if dt.Name != "EGLDisplay" && dt.Name != "EGLConfig" {
 		return false
 	}
-	// Check that the typedef is "typedef void *EGLDisplay".
+	// Check that the typedef is "typedef void *<name>".
 	if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
 		if _, ok := ptr.Type.(*dwarf.VoidType); ok {
 			return true
diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go
index 4d66e1b..a5a22c8 100644
--- a/libgo/go/cmd/cgo/out.go
+++ b/libgo/go/cmd/cgo/out.go
@@ -22,6 +22,7 @@
 	"regexp"
 	"sort"
 	"strings"
+	"unicode"
 )
 
 var (
@@ -102,6 +103,11 @@
 
 	typedefNames := make([]string, 0, len(typedef))
 	for name := range typedef {
+		if name == "_Ctype_void" {
+			// We provide an appropriate declaration for
+			// _Ctype_void below (#39877).
+			continue
+		}
 		typedefNames = append(typedefNames, name)
 	}
 	sort.Strings(typedefNames)
@@ -807,6 +813,28 @@
 	return s + "))"
 }
 
+// exportParamName returns the value of param as it should be
+// displayed in a c header file. If param contains any non-ASCII
+// characters, this function will return the character p followed by
+// the value of position; otherwise, this function will return the
+// value of param.
+func exportParamName(param string, position int) string {
+	if param == "" {
+		return fmt.Sprintf("p%d", position)
+	}
+
+	pname := param
+
+	for i := 0; i < len(param); i++ {
+		if param[i] > unicode.MaxASCII {
+			pname = fmt.Sprintf("p%d", position)
+			break
+		}
+	}
+
+	return pname
+}
+
 // Write out the various stubs we need to support functions exported
 // from Go so that they are callable from C.
 func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
@@ -920,42 +948,45 @@
 				if i > 0 || fn.Recv != nil {
 					s += ", "
 				}
-				s += fmt.Sprintf("%s p%d", p.cgoType(atype).C, i)
+				s += fmt.Sprintf("%s %s", p.cgoType(atype).C, exportParamName(aname, i))
 			})
 		s += ")"
 
 		if len(exp.Doc) > 0 {
 			fmt.Fprintf(fgcch, "\n%s", exp.Doc)
+			if !strings.HasSuffix(exp.Doc, "\n") {
+				fmt.Fprint(fgcch, "\n")
+			}
 		}
-		fmt.Fprintf(fgcch, "\nextern %s;\n", s)
+		fmt.Fprintf(fgcch, "extern %s;\n", s)
 
 		fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *, int, __SIZE_TYPE__);\n", cPrefix, exp.ExpName)
 		fmt.Fprintf(fgcc, "\nCGO_NO_SANITIZE_THREAD")
 		fmt.Fprintf(fgcc, "\n%s\n", s)
 		fmt.Fprintf(fgcc, "{\n")
 		fmt.Fprintf(fgcc, "\t__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();\n")
-		fmt.Fprintf(fgcc, "\t%s %v a;\n", ctype, p.packedAttribute())
+		fmt.Fprintf(fgcc, "\t%s %v _cgo_a;\n", ctype, p.packedAttribute())
 		if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) {
 			fmt.Fprintf(fgcc, "\t%s r;\n", gccResult)
 		}
 		if fn.Recv != nil {
-			fmt.Fprintf(fgcc, "\ta.recv = recv;\n")
+			fmt.Fprintf(fgcc, "\t_cgo_a.recv = recv;\n")
 		}
 		forFieldList(fntype.Params,
 			func(i int, aname string, atype ast.Expr) {
-				fmt.Fprintf(fgcc, "\ta.p%d = p%d;\n", i, i)
+				fmt.Fprintf(fgcc, "\t_cgo_a.p%d = %s;\n", i, exportParamName(aname, i))
 			})
 		fmt.Fprintf(fgcc, "\t_cgo_tsan_release();\n")
-		fmt.Fprintf(fgcc, "\tcrosscall2(_cgoexp%s_%s, &a, %d, _cgo_ctxt);\n", cPrefix, exp.ExpName, off)
+		fmt.Fprintf(fgcc, "\tcrosscall2(_cgoexp%s_%s, &_cgo_a, %d, _cgo_ctxt);\n", cPrefix, exp.ExpName, off)
 		fmt.Fprintf(fgcc, "\t_cgo_tsan_acquire();\n")
 		fmt.Fprintf(fgcc, "\t_cgo_release_context(_cgo_ctxt);\n")
 		if gccResult != "void" {
 			if len(fntype.Results.List) == 1 && len(fntype.Results.List[0].Names) <= 1 {
-				fmt.Fprintf(fgcc, "\treturn a.r0;\n")
+				fmt.Fprintf(fgcc, "\treturn _cgo_a.r0;\n")
 			} else {
 				forFieldList(fntype.Results,
 					func(i int, aname string, atype ast.Expr) {
-						fmt.Fprintf(fgcc, "\tr.r%d = a.r%d;\n", i, i)
+						fmt.Fprintf(fgcc, "\tr.r%d = _cgo_a.r%d;\n", i, i)
 					})
 				fmt.Fprintf(fgcc, "\treturn r;\n")
 			}
diff --git a/libgo/go/cmd/go/alldocs.go b/libgo/go/cmd/go/alldocs.go
index c2678c3..68bad3c 100644
--- a/libgo/go/cmd/go/alldocs.go
+++ b/libgo/go/cmd/go/alldocs.go
@@ -35,23 +35,24 @@
 //
 // Additional help topics:
 //
-// 	buildmode   build modes
-// 	c           calling between Go and C
-// 	cache       build and test caching
-// 	environment environment variables
-// 	filetype    file types
-// 	go.mod      the go.mod file
-// 	gopath      GOPATH environment variable
-// 	gopath-get  legacy GOPATH go get
-// 	goproxy     module proxy protocol
-// 	importpath  import path syntax
-// 	modules     modules, module versions, and more
-// 	module-get  module-aware go get
-// 	module-auth module authentication using go.sum
-// 	module-private module configuration for non-public modules
-// 	packages    package lists and patterns
-// 	testflag    testing flags
-// 	testfunc    testing functions
+// 	buildconstraint build constraints
+// 	buildmode       build modes
+// 	c               calling between Go and C
+// 	cache           build and test caching
+// 	environment     environment variables
+// 	filetype        file types
+// 	go.mod          the go.mod file
+// 	gopath          GOPATH environment variable
+// 	gopath-get      legacy GOPATH go get
+// 	goproxy         module proxy protocol
+// 	importpath      import path syntax
+// 	modules         modules, module versions, and more
+// 	module-get      module-aware go get
+// 	module-auth     module authentication using go.sum
+// 	module-private  module configuration for non-public modules
+// 	packages        package lists and patterns
+// 	testflag        testing flags
+// 	testfunc        testing functions
 //
 // Use "go help <topic>" for more information about that topic.
 //
@@ -547,6 +548,9 @@
 // tag "generate" so that files may be examined by go generate but ignored
 // during build.
 //
+// For packages with invalid code, generate processes only source files with a
+// valid package clause.
+//
 // If any generator returns an error exit status, "go generate" skips
 // all further processing for that package.
 //
@@ -657,7 +661,10 @@
 // this automatically as well.
 //
 // The -insecure flag permits fetching from repositories and resolving
-// custom domains using insecure schemes such as HTTP. Use with caution.
+// custom domains using insecure schemes such as HTTP. Use with caution. The
+// GOINSECURE environment variable is usually a better alternative, since it
+// provides control over which modules may be retrieved using an insecure scheme.
+// See 'go help environment' for details.
 //
 // The second step is to download (if needed), build, and install
 // the named packages.
@@ -1017,7 +1024,8 @@
 //
 // Download downloads the named modules, which can be module patterns selecting
 // dependencies of the main module or module queries of the form path@version.
-// With no arguments, download applies to all dependencies of the main module.
+// With no arguments, download applies to all dependencies of the main module
+// (equivalent to 'go mod download all').
 //
 // The go command will automatically download modules as needed during ordinary
 // execution. The "go mod download" command is useful mainly for pre-filling
@@ -1305,10 +1313,10 @@
 // and its test source files to identify significant problems. If go vet
 // finds any problems, go test reports those and does not run the test
 // binary. Only a high-confidence subset of the default go vet checks are
-// used. That subset is: 'atomic', 'bool', 'buildtags', 'nilfunc', and
-// 'printf'. You can see the documentation for these and other vet tests
-// via "go doc cmd/vet". To disable the running of go vet, use the
-// -vet=off flag.
+// used. That subset is: 'atomic', 'bool', 'buildtags', 'errorsas',
+// 'ifaceassert', 'nilfunc', 'printf', and 'stringintconv'. You can see
+// the documentation for these and other vet tests via "go doc cmd/vet".
+// To disable the running of go vet, use the -vet=off flag.
 //
 // All test output and summary lines are printed to the go command's
 // standard output, even if the test printed them to its own standard
@@ -1470,6 +1478,95 @@
 // See also: go fmt, go fix.
 //
 //
+// Build constraints
+//
+// A build constraint, also known as a build tag, is a line comment that begins
+//
+// 	// +build
+//
+// that lists the conditions under which a file should be included in the package.
+// Constraints may appear in any kind of source file (not just Go), but
+// they must appear near the top of the file, preceded
+// only by blank lines and other line comments. These rules mean that in Go
+// files a build constraint must appear before the package clause.
+//
+// To distinguish build constraints from package documentation, a series of
+// build constraints must be followed by a blank line.
+//
+// A build constraint is evaluated as the OR of space-separated options.
+// Each option evaluates as the AND of its comma-separated terms.
+// Each term consists of letters, digits, underscores, and dots.
+// A term may be negated with a preceding !.
+// For example, the build constraint:
+//
+// 	// +build linux,386 darwin,!cgo
+//
+// corresponds to the boolean formula:
+//
+// 	(linux AND 386) OR (darwin AND (NOT cgo))
+//
+// A file may have multiple build constraints. The overall constraint is the AND
+// of the individual constraints. That is, the build constraints:
+//
+// 	// +build linux darwin
+// 	// +build amd64
+//
+// corresponds to the boolean formula:
+//
+// 	(linux OR darwin) AND amd64
+//
+// During a particular build, the following words are satisfied:
+//
+// 	- the target operating system, as spelled by runtime.GOOS, set with the
+// 	  GOOS environment variable.
+// 	- the target architecture, as spelled by runtime.GOARCH, set with the
+// 	  GOARCH environment variable.
+// 	- the compiler being used, either "gc" or "gccgo"
+// 	- "cgo", if the cgo command is supported (see CGO_ENABLED in
+// 	  'go help environment').
+// 	- a term for each Go major release, through the current version:
+// 	  "go1.1" from Go version 1.1 onward, "go1.12" from Go 1.12, and so on.
+// 	- any additional tags given by the -tags flag (see 'go help build').
+//
+// There are no separate build tags for beta or minor releases.
+//
+// If a file's name, after stripping the extension and a possible _test suffix,
+// matches any of the following patterns:
+// 	*_GOOS
+// 	*_GOARCH
+// 	*_GOOS_GOARCH
+// (example: source_windows_amd64.go) where GOOS and GOARCH represent
+// any known operating system and architecture values respectively, then
+// the file is considered to have an implicit build constraint requiring
+// those terms (in addition to any explicit constraints in the file).
+//
+// Using GOOS=android matches build tags and files as for GOOS=linux
+// in addition to android tags and files.
+//
+// Using GOOS=illumos matches build tags and files as for GOOS=solaris
+// in addition to illumos tags and files.
+//
+// To keep a file from being considered for the build:
+//
+// 	// +build ignore
+//
+// (any other unsatisfied word will work as well, but "ignore" is conventional.)
+//
+// To build a file only when using cgo, and only on Linux and OS X:
+//
+// 	// +build linux,cgo darwin,cgo
+//
+// Such a file is usually paired with another file implementing the
+// default functionality for other systems, which in this case would
+// carry the constraint:
+//
+// 	// +build !linux,!darwin !cgo
+//
+// Naming a file dns_windows.go will cause it to be included only when
+// building the package for Windows; similarly, math_386.s will be included
+// only when building the package for 32-bit x86.
+//
+//
 // Build modes
 //
 // The 'go build' and 'go install' commands take a -buildmode argument which
@@ -1603,6 +1700,8 @@
 // 	GOCACHE
 // 		The directory where the go command will store cached
 // 		information for reuse in future builds.
+// 	GOMODCACHE
+// 		The directory where the go command will store downloaded modules.
 // 	GODEBUG
 // 		Enable various debugging facilities. See 'go doc runtime'
 // 		for details.
@@ -1620,6 +1719,9 @@
 // 		Comma-separated list of glob patterns (in the syntax of Go's path.Match)
 // 		of module path prefixes that should always be fetched in an insecure
 // 		manner. Only applies to dependencies that are being fetched directly.
+// 		Unlike the -insecure flag on 'go get', GOINSECURE does not disable
+// 		checksum database validation. GOPRIVATE or GONOSUMDB may be used
+// 		to achieve that.
 // 	GOOS
 // 		The operating system for which to compile code.
 // 		Examples are linux, darwin, windows, netbsd.
@@ -2693,15 +2795,15 @@
 // Go module mirror run by Google and fall back to a direct connection
 // if the proxy reports that it does not have the module (HTTP error 404 or 410).
 // See https://proxy.golang.org/privacy for the service's privacy policy.
-// If GOPROXY is set to the string "direct", downloads use a direct connection
-// to source control servers. Setting GOPROXY to "off" disallows downloading
-// modules from any source. Otherwise, GOPROXY is expected to be a comma-separated
-// list of the URLs of module proxies, in which case the go command will fetch
-// modules from those proxies. For each request, the go command tries each proxy
-// in sequence, only moving to the next if the current proxy returns a 404 or 410
-// HTTP response. The string "direct" may appear in the proxy list,
-// to cause a direct connection to be attempted at that point in the search.
-// Any proxies listed after "direct" are never consulted.
+//
+// If GOPROXY is set to the string "direct", downloads use a direct connection to
+// source control servers. Setting GOPROXY to "off" disallows downloading modules
+// from any source. Otherwise, GOPROXY is expected to be list of module proxy URLs
+// separated by either comma (,) or pipe (|) characters, which control error
+// fallback behavior. For each request, the go command tries each proxy in
+// sequence. If there is an error, the go command will try the next proxy in the
+// list if the error is a 404 or 410 HTTP response or if the current proxy is
+// followed by a pipe character, indicating it is safe to fall back on any error.
 //
 // The GOPRIVATE and GONOPROXY environment variables allow bypassing
 // the proxy for selected modules. See 'go help module-private' for details.
diff --git a/libgo/go/cmd/go/go_test.go b/libgo/go/cmd/go/go_test.go
index 40999f2..021930a 100644
--- a/libgo/go/cmd/go/go_test.go
+++ b/libgo/go/cmd/go/go_test.go
@@ -6,9 +6,9 @@
 
 import (
 	"bytes"
-	"context"
 	"debug/elf"
 	"debug/macho"
+	"debug/pe"
 	"flag"
 	"fmt"
 	"go/format"
@@ -60,7 +60,7 @@
 		canRun = false
 	case "darwin":
 		switch runtime.GOARCH {
-		case "arm", "arm64":
+		case "arm64":
 			canRun = false
 		}
 	case "linux":
@@ -113,12 +113,6 @@
 var testTmpDir string
 var testBin string
 
-// testCtx is canceled when the test binary is about to time out.
-//
-// If https://golang.org/issue/28135 is accepted, uses of this variable in test
-// functions should be replaced by t.Context().
-var testCtx = context.Background()
-
 // The TestMain function creates a go command for testing purposes and
 // deletes it after the tests have been run.
 func TestMain(m *testing.M) {
@@ -130,23 +124,9 @@
 		fmt.Printf("SKIP\n")
 		return
 	}
-	os.Unsetenv("GOROOT_FINAL")
 
 	flag.Parse()
 
-	timeoutFlag := flag.Lookup("test.timeout")
-	if timeoutFlag != nil {
-		// TODO(golang.org/issue/28147): The go command does not pass the
-		// test.timeout flag unless either -timeout or -test.timeout is explicitly
-		// set on the command line.
-		if d := timeoutFlag.Value.(flag.Getter).Get().(time.Duration); d != 0 {
-			aBitShorter := d * 95 / 100
-			var cancel context.CancelFunc
-			testCtx, cancel = context.WithTimeout(testCtx, aBitShorter)
-			defer cancel()
-		}
-	}
-
 	if *proxyAddr != "" {
 		StartProxy()
 		select {}
@@ -198,6 +178,12 @@
 			return strings.TrimSpace(string(out))
 		}
 		testGOROOT = goEnv("GOROOT")
+		os.Setenv("TESTGO_GOROOT", testGOROOT)
+		// Ensure that GOROOT is set explicitly.
+		// Otherwise, if the toolchain was built with GOROOT_FINAL set but has not
+		// yet been moved to its final location, programs that invoke runtime.GOROOT
+		// may accidentally use the wrong path.
+		os.Setenv("GOROOT", testGOROOT)
 
 		// The whole GOROOT/pkg tree was installed using the GOHOSTOS/GOHOSTARCH
 		// toolchain (installed in GOROOT/pkg/tool/GOHOSTOS_GOHOSTARCH).
@@ -234,8 +220,10 @@
 		}
 		testCC = strings.TrimSpace(string(out))
 
-		if out, err := exec.Command(testGo, "env", "CGO_ENABLED").Output(); err != nil {
-			fmt.Fprintf(os.Stderr, "running testgo failed: %v\n", err)
+		cmd := exec.Command(testGo, "env", "CGO_ENABLED")
+		cmd.Stderr = new(strings.Builder)
+		if out, err := cmd.Output(); err != nil {
+			fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr)
 			canRun = false
 		} else {
 			canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
@@ -317,7 +305,6 @@
 type testgoData struct {
 	t              *testing.T
 	temps          []string
-	wd             string
 	env            []string
 	tempdir        string
 	ran            bool
@@ -367,9 +354,6 @@
 	if tg.ran {
 		tg.t.Fatal("internal testsuite error: call to parallel after run")
 	}
-	if tg.wd != "" {
-		tg.t.Fatal("internal testsuite error: call to parallel after cd")
-	}
 	for _, e := range tg.env {
 		if strings.HasPrefix(e, "GOROOT=") || strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
 			val := e[strings.Index(e, "=")+1:]
@@ -392,24 +376,6 @@
 	return wd
 }
 
-// cd changes the current directory to the named directory. Note that
-// using this means that the test must not be run in parallel with any
-// other tests.
-func (tg *testgoData) cd(dir string) {
-	tg.t.Helper()
-	if tg.inParallel {
-		tg.t.Fatal("internal testsuite error: changing directory when running in parallel")
-	}
-	if tg.wd == "" {
-		tg.wd = tg.pwd()
-	}
-	abs, err := filepath.Abs(dir)
-	tg.must(os.Chdir(dir))
-	if err == nil {
-		tg.setenv("PWD", abs)
-	}
-}
-
 // sleep sleeps for one tick, where a tick is a conservative estimate
 // of how long it takes for a file modification to get a different
 // mtime.
@@ -680,15 +646,6 @@
 	if filepath.IsAbs(path) && !strings.HasPrefix(path, tg.tempdir) {
 		tg.t.Fatalf("internal testsuite error: creatingTemp(%q) with absolute path not in temporary directory", path)
 	}
-	// If we have changed the working directory, make sure we have
-	// an absolute path, because we are going to change directory
-	// back before we remove the temporary.
-	if !filepath.IsAbs(path) {
-		if tg.wd == "" || strings.HasPrefix(tg.wd, testGOROOT) {
-			tg.t.Fatalf("internal testsuite error: creatingTemp(%q) within GOROOT/src", path)
-		}
-		path = filepath.Join(tg.wd, path)
-	}
 	tg.must(robustio.RemoveAll(path))
 	tg.temps = append(tg.temps, path)
 }
@@ -788,21 +745,6 @@
 	}
 }
 
-// wantArchive fails if path is not an archive.
-func (tg *testgoData) wantArchive(path string) {
-	tg.t.Helper()
-	f, err := os.Open(path)
-	if err != nil {
-		tg.t.Fatal(err)
-	}
-	buf := make([]byte, 100)
-	io.ReadFull(f, buf)
-	f.Close()
-	if !bytes.HasPrefix(buf, []byte("!<arch>\n")) {
-		tg.t.Fatalf("file %s exists but is not an archive", path)
-	}
-}
-
 // isStale reports whether pkg is stale, and why
 func (tg *testgoData) isStale(pkg string) (bool, string) {
 	tg.t.Helper()
@@ -857,16 +799,6 @@
 // cleanup cleans up a test that runs testgo.
 func (tg *testgoData) cleanup() {
 	tg.t.Helper()
-	if tg.wd != "" {
-		wd, _ := os.Getwd()
-		tg.t.Logf("ended in %s", wd)
-
-		if err := os.Chdir(tg.wd); err != nil {
-			// We are unlikely to be able to continue.
-			fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err)
-			os.Exit(2)
-		}
-	}
 	if *testWork {
 		tg.t.Logf("TESTWORK=%s\n", tg.path("."))
 		return
@@ -883,10 +815,9 @@
 	// module cache has 0444 directories;
 	// make them writable in order to remove content.
 	filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
-		if err != nil {
-			return nil // ignore errors walking in file system
-		}
-		if info.IsDir() {
+		// chmod not only directories, but also things that we couldn't even stat
+		// due to permission errors: they may also be unreadable directories.
+		if err != nil || info.IsDir() {
 			os.Chmod(path, 0777)
 		}
 		return nil
@@ -1012,35 +943,6 @@
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
 }
 
-func TestInternalPackagesInGOROOTAreRespected(t *testing.T) {
-	skipIfGccgo(t, "gccgo does not have GOROOT")
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.runFail("build", "-v", "./testdata/testinternal")
-	tg.grepBoth(`testinternal(\/|\\)p\.go\:3\:8\: use of internal package net/http/internal not allowed`, "wrong error message for testdata/testinternal")
-}
-
-func TestInternalPackagesOutsideGOROOTAreRespected(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.runFail("build", "-v", "./testdata/testinternal2")
-	tg.grepBoth(`testinternal2(\/|\\)p\.go\:3\:8\: use of internal package .*internal/w not allowed`, "wrote error message for testdata/testinternal2")
-}
-
-func TestInternalPackageErrorsAreHandled(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("list", "./testdata/testinternal3")
-}
-
-func TestInternalCache(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testinternal4"))
-	tg.runFail("build", "p")
-	tg.grepStderr("internal", "did not fail to build p")
-}
-
 // cmd/go: custom import path checking should not apply to Go packages without import comment.
 func TestIssue10952(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
@@ -1128,6 +1030,7 @@
 func TestAccidentalGitCheckout(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExecPath(t, "git")
+	testenv.MustHaveExecPath(t, "svn")
 
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -1146,87 +1049,6 @@
 	}
 }
 
-func TestRelativeImportsGoTest(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "./testdata/testimport")
-}
-
-func TestRelativeImportsGoTestDashI(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	// don't let test -i overwrite runtime
-	tg.wantNotStale("runtime", "", "must be non-stale before test -i")
-
-	tg.run("test", "-i", "./testdata/testimport")
-}
-
-func TestRelativeImportsInCommandLinePackage(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	files, err := filepath.Glob("./testdata/testimport/*.go")
-	tg.must(err)
-	tg.run(append([]string{"test"}, files...)...)
-}
-
-func TestVersionControlErrorMessageIncludesCorrectDirectory(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/shadow/root1"))
-	tg.runFail("get", "-u", "foo")
-
-	// TODO(iant): We should not have to use strconv.Quote here.
-	// The code in vcs.go should be changed so that it is not required.
-	quoted := strconv.Quote(filepath.Join("testdata", "shadow", "root1", "src", "foo"))
-	quoted = quoted[1 : len(quoted)-1]
-
-	tg.grepStderr(regexp.QuoteMeta(quoted), "go get -u error does not mention shadow/root1/src/foo")
-}
-
-func TestInstallFailsWithNoBuildableFiles(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.setenv("CGO_ENABLED", "0")
-	tg.runFail("install", "cgotest")
-	tg.grepStderr("build constraints exclude all Go files", "go install cgotest did not report 'build constraints exclude all Go files'")
-}
-
-// Issue 21895
-func TestMSanAndRaceRequireCgo(t *testing.T) {
-	if !canMSan && !canRace {
-		t.Skip("skipping because both msan and the race detector are not supported")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempFile("triv.go", `package main; func main() {}`)
-	tg.setenv("CGO_ENABLED", "0")
-	if canRace {
-		tg.runFail("install", "-race", "triv.go")
-		tg.grepStderr("-race requires cgo", "did not correctly report that -race requires cgo")
-		tg.grepStderrNot("-msan", "reported that -msan instead of -race requires cgo")
-	}
-	if canMSan {
-		tg.runFail("install", "-msan", "triv.go")
-		tg.grepStderr("-msan requires cgo", "did not correctly report that -msan requires cgo")
-		tg.grepStderrNot("-race", "reported that -race instead of -msan requires cgo")
-	}
-}
-
-func TestRelativeGOBINFail(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempFile("triv.go", `package main; func main() {}`)
-	tg.cd(tg.path("."))
-	tg.setenv("GOBIN", ".")
-	tg.cd(tg.path("."))
-	tg.runFail("install")
-	tg.grepStderr("cannot install, GOBIN must be an absolute path", "go install must fail if $GOBIN is a relative path")
-}
-
 func TestPackageMainTestCompilerFlags(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -1240,54 +1062,6 @@
 	tg.grepStderr(`([\\/]compile|gccgo).* (-p p1|-fgo-pkgpath=p1).*p1\.go`, "should have run compile -p p1 p1.go")
 }
 
-// Issue 12690
-func TestPackageNotStaleWithTrailingSlash(t *testing.T) {
-	skipIfGccgo(t, "gccgo does not have GOROOT")
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	// Make sure the packages below are not stale.
-	tg.wantNotStale("runtime", "", "must be non-stale before test runs")
-	tg.wantNotStale("os", "", "must be non-stale before test runs")
-	tg.wantNotStale("io", "", "must be non-stale before test runs")
-
-	goroot := runtime.GOROOT()
-	tg.setenv("GOROOT", goroot+"/")
-
-	tg.wantNotStale("runtime", "", "with trailing slash in GOROOT, runtime listed as stale")
-	tg.wantNotStale("os", "", "with trailing slash in GOROOT, os listed as stale")
-	tg.wantNotStale("io", "", "with trailing slash in GOROOT, io listed as stale")
-}
-
-func TestGoGetNonPkg(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempDir("gobin")
-	tg.setenv("GOPATH", tg.path("."))
-	tg.setenv("GOBIN", tg.path("gobin"))
-	tg.runFail("get", "-d", "golang.org/x/tools")
-	tg.grepStderr("golang.org/x/tools: no Go files", "missing error")
-	tg.runFail("get", "-d", "-u", "golang.org/x/tools")
-	tg.grepStderr("golang.org/x/tools: no Go files", "missing error")
-	tg.runFail("get", "-d", "golang.org/x/tools")
-	tg.grepStderr("golang.org/x/tools: no Go files", "missing error")
-}
-
-func TestGoGetTestOnlyPkg(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempDir("gopath")
-	tg.setenv("GOPATH", tg.path("gopath"))
-	tg.run("get", "golang.org/x/tour/content...")
-	tg.run("get", "-t", "golang.org/x/tour/content...")
-}
-
 // Issue 4104.
 func TestGoTestWithPackageListedMultipleTimes(t *testing.T) {
 	tooSlow(t)
@@ -1338,19 +1112,6 @@
 	}
 }
 
-func TestGoListDedupsPackages(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.run("list", "xtestonly", "./testdata/src/xtestonly/...")
-	got := strings.TrimSpace(tg.getStdout())
-	const want = "xtestonly"
-	if got != want {
-		t.Errorf("got %q; want %q", got, want)
-	}
-}
-
 func TestGoListDeps(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -1618,57 +1379,6 @@
 	tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
 }
 
-// Issue 4186. go get cannot be used to download packages to $GOROOT.
-// Test that without GOPATH set, go get should fail.
-func TestGoGetIntoGOROOT(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.tempDir("src")
-
-	// Fails because GOROOT=GOPATH
-	tg.setenv("GOPATH", tg.path("."))
-	tg.setenv("GOROOT", tg.path("."))
-	tg.runFail("get", "-d", "github.com/golang/example/hello")
-	tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
-	tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
-
-	// Fails because GOROOT=GOPATH after cleaning.
-	tg.setenv("GOPATH", tg.path(".")+"/")
-	tg.setenv("GOROOT", tg.path("."))
-	tg.runFail("get", "-d", "github.com/golang/example/hello")
-	tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
-	tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
-
-	tg.setenv("GOPATH", tg.path("."))
-	tg.setenv("GOROOT", tg.path(".")+"/")
-	tg.runFail("get", "-d", "github.com/golang/example/hello")
-	tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
-	tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
-
-	// Fails because GOROOT=$HOME/go so default GOPATH unset.
-	tg.tempDir("home/go")
-	tg.setenv(homeEnvName(), tg.path("home"))
-	tg.setenv("GOPATH", "")
-	tg.setenv("GOROOT", tg.path("home/go"))
-	tg.runFail("get", "-d", "github.com/golang/example/hello")
-	tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
-
-	tg.setenv(homeEnvName(), tg.path("home")+"/")
-	tg.setenv("GOPATH", "")
-	tg.setenv("GOROOT", tg.path("home/go"))
-	tg.runFail("get", "-d", "github.com/golang/example/hello")
-	tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
-
-	tg.setenv(homeEnvName(), tg.path("home"))
-	tg.setenv("GOPATH", "")
-	tg.setenv("GOROOT", tg.path("home/go")+"/")
-	tg.runFail("get", "-d", "github.com/golang/example/hello")
-	tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
-}
-
 func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
 	skipIfGccgo(t, "gccgo does not support -ldflags -X")
 	tooSlow(t)
@@ -1684,54 +1394,6 @@
 	tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`)
 }
 
-func TestGoTestCpuprofileLeavesBinaryBehind(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no standard packages")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.makeTempdir()
-	tg.cd(tg.path("."))
-	tg.run("test", "-cpuprofile", "errors.prof", "errors")
-	tg.wantExecutable("errors.test"+exeSuffix, "go test -cpuprofile did not create errors.test")
-}
-
-func TestGoTestCpuprofileDashOControlsBinaryLocation(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no standard packages")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.makeTempdir()
-	tg.cd(tg.path("."))
-	tg.run("test", "-cpuprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors")
-	tg.wantExecutable("myerrors.test"+exeSuffix, "go test -cpuprofile -o myerrors.test did not create myerrors.test")
-}
-
-func TestGoTestMutexprofileLeavesBinaryBehind(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no standard packages")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.makeTempdir()
-	tg.cd(tg.path("."))
-	tg.run("test", "-mutexprofile", "errors.prof", "errors")
-	tg.wantExecutable("errors.test"+exeSuffix, "go test -mutexprofile did not create errors.test")
-}
-
-func TestGoTestMutexprofileDashOControlsBinaryLocation(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no standard packages")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.makeTempdir()
-	tg.cd(tg.path("."))
-	tg.run("test", "-mutexprofile", "errors.prof", "-o", "myerrors.test"+exeSuffix, "errors")
-	tg.wantExecutable("myerrors.test"+exeSuffix, "go test -mutexprofile -o myerrors.test did not create myerrors.test")
-}
-
 func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) {
 	skipIfGccgo(t, "gccgo has no standard packages")
 	tooSlow(t)
@@ -1770,88 +1432,6 @@
 	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
 }
 
-// Issue 4568.
-func TestSymlinksList(t *testing.T) {
-	testenv.MustHaveSymlink(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.tempDir("src")
-	tg.must(os.Symlink(tg.path("."), tg.path("src/dir1")))
-	tg.tempFile("src/dir1/p.go", "package p")
-	tg.setenv("GOPATH", tg.path("."))
-	tg.cd(tg.path("src"))
-	tg.run("list", "-f", "{{.Root}}", "dir1")
-	if strings.TrimSpace(tg.getStdout()) != tg.path(".") {
-		t.Error("confused by symlinks")
-	}
-}
-
-// Issue 14054.
-func TestSymlinksVendor(t *testing.T) {
-	testenv.MustHaveSymlink(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.tempDir("gopath/src/dir1/vendor/v")
-	tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `v`\nfunc main(){}")
-	tg.tempFile("gopath/src/dir1/vendor/v/v.go", "package v")
-	tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
-	tg.setenv("GOPATH", tg.path("gopath"))
-	tg.cd(tg.path("symdir1"))
-	tg.run("list", "-f", "{{.Root}}", ".")
-	if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
-		t.Error("list confused by symlinks")
-	}
-
-	// All of these should succeed, not die in vendor-handling code.
-	tg.run("run", "p.go")
-	tg.run("build")
-	tg.run("install")
-}
-
-// Issue 15201.
-func TestSymlinksVendor15201(t *testing.T) {
-	testenv.MustHaveSymlink(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	tg.tempDir("gopath/src/x/y/_vendor/src/x")
-	tg.must(os.Symlink("../../..", tg.path("gopath/src/x/y/_vendor/src/x/y")))
-	tg.tempFile("gopath/src/x/y/w/w.go", "package w\nimport \"x/y/z\"\n")
-	tg.must(os.Symlink("../_vendor/src", tg.path("gopath/src/x/y/w/vendor")))
-	tg.tempFile("gopath/src/x/y/z/z.go", "package z\n")
-
-	tg.setenv("GOPATH", tg.path("gopath/src/x/y/_vendor")+string(filepath.ListSeparator)+tg.path("gopath"))
-	tg.cd(tg.path("gopath/src"))
-	tg.run("list", "./...")
-}
-
-func TestSymlinksInternal(t *testing.T) {
-	testenv.MustHaveSymlink(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempDir("gopath/src/dir1/internal/v")
-	tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `dir1/internal/v`\nfunc main(){}")
-	tg.tempFile("gopath/src/dir1/internal/v/v.go", "package v")
-	tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
-	tg.setenv("GOPATH", tg.path("gopath"))
-	tg.cd(tg.path("symdir1"))
-	tg.run("list", "-f", "{{.Root}}", ".")
-	if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
-		t.Error("list confused by symlinks")
-	}
-
-	// All of these should succeed, not die in internal-handling code.
-	tg.run("run", "p.go")
-	tg.run("build")
-	tg.run("install")
-}
-
 // Issue 4515.
 func TestInstallWithTags(t *testing.T) {
 	tooSlow(t)
@@ -1880,52 +1460,6 @@
 	}
 }
 
-// Issue 4773
-func TestCaseCollisions(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.tempDir("src/example/a/pkg")
-	tg.tempDir("src/example/a/Pkg")
-	tg.tempDir("src/example/b")
-	tg.setenv("GOPATH", tg.path("."))
-	tg.tempFile("src/example/a/a.go", `package p
-		import (
-			_ "example/a/pkg"
-			_ "example/a/Pkg"
-		)`)
-	tg.tempFile("src/example/a/pkg/pkg.go", `package pkg`)
-	tg.tempFile("src/example/a/Pkg/pkg.go", `package pkg`)
-	tg.run("list", "-json", "example/a")
-	tg.grepStdout("case-insensitive import collision", "go list -json example/a did not report import collision")
-	tg.runFail("build", "example/a")
-	tg.grepStderr("case-insensitive import collision", "go build example/a did not report import collision")
-	tg.tempFile("src/example/b/file.go", `package b`)
-	tg.tempFile("src/example/b/FILE.go", `package b`)
-	f, err := os.Open(tg.path("src/example/b"))
-	tg.must(err)
-	names, err := f.Readdirnames(0)
-	tg.must(err)
-	tg.check(f.Close())
-	args := []string{"list"}
-	if len(names) == 2 {
-		// case-sensitive file system, let directory read find both files
-		args = append(args, "example/b")
-	} else {
-		// case-insensitive file system, list files explicitly on command line
-		args = append(args, tg.path("src/example/b/file.go"), tg.path("src/example/b/FILE.go"))
-	}
-	tg.runFail(args...)
-	tg.grepStderr("case-insensitive file name collision", "go list example/b did not report file name collision")
-
-	tg.runFail("list", "example/a/pkg", "example/a/Pkg")
-	tg.grepStderr("case-insensitive import collision", "go list example/a/pkg example/a/Pkg did not report import collision")
-	tg.run("list", "-json", "-e", "example/a/pkg", "example/a/Pkg")
-	tg.grepStdout("case-insensitive import collision", "go list -json -e example/a/pkg example/a/Pkg did not report import collision")
-	tg.runFail("build", "example/a/pkg", "example/a/Pkg")
-	tg.grepStderr("case-insensitive import collision", "go build example/a/pkg example/a/Pkg did not report import collision")
-}
-
 // Issue 17451, 17662.
 func TestSymlinkWarning(t *testing.T) {
 	tg := testgo(t)
@@ -1951,334 +1485,6 @@
 	tg.grepStderr("ignoring symlink", "list should have reported symlink")
 }
 
-// Issue 8181.
-func TestGoGetDashTIssue8181(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-	tg.run("get", "-v", "-t", "github.com/rsc/go-get-issue-8181/a", "github.com/rsc/go-get-issue-8181/b")
-	tg.run("list", "...")
-	tg.grepStdout("x/build/gerrit", "missing expected x/build/gerrit")
-}
-
-func TestIssue11307(t *testing.T) {
-	// go get -u was not working except in checkout directory
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-	tg.run("get", "github.com/rsc/go-get-issue-11307")
-	tg.run("get", "-u", "github.com/rsc/go-get-issue-11307") // was failing
-}
-
-func TestShadowingLogic(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no standard packages")
-	tg := testgo(t)
-	defer tg.cleanup()
-	pwd := tg.pwd()
-	sep := string(filepath.ListSeparator)
-	tg.setenv("GOPATH", filepath.Join(pwd, "testdata", "shadow", "root1")+sep+filepath.Join(pwd, "testdata", "shadow", "root2"))
-
-	// The math in root1 is not "math" because the standard math is.
-	tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/math")
-	pwdForwardSlash := strings.ReplaceAll(pwd, string(os.PathSeparator), "/")
-	if !strings.HasPrefix(pwdForwardSlash, "/") {
-		pwdForwardSlash = "/" + pwdForwardSlash
-	}
-	// The output will have makeImportValid applies, but we only
-	// bother to deal with characters we might reasonably see.
-	for _, r := range " :" {
-		pwdForwardSlash = strings.ReplaceAll(pwdForwardSlash, string(r), "_")
-	}
-	want := "(_" + pwdForwardSlash + "/testdata/shadow/root1/src/math) (" + filepath.Join(runtime.GOROOT(), "src", "math") + ")"
-	if strings.TrimSpace(tg.getStdout()) != want {
-		t.Error("shadowed math is not shadowed; looking for", want)
-	}
-
-	// The foo in root1 is "foo".
-	tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root1/src/foo")
-	if strings.TrimSpace(tg.getStdout()) != "(foo) ()" {
-		t.Error("unshadowed foo is shadowed")
-	}
-
-	// The foo in root2 is not "foo" because the foo in root1 got there first.
-	tg.run("list", "-f", "({{.ImportPath}}) ({{.ConflictDir}})", "./testdata/shadow/root2/src/foo")
-	want = "(_" + pwdForwardSlash + "/testdata/shadow/root2/src/foo) (" + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo") + ")"
-	if strings.TrimSpace(tg.getStdout()) != want {
-		t.Error("shadowed foo is not shadowed; looking for", want)
-	}
-
-	// The error for go install should mention the conflicting directory.
-	tg.runFail("install", "./testdata/shadow/root2/src/foo")
-	want = "go install: no install location for " + filepath.Join(pwd, "testdata", "shadow", "root2", "src", "foo") + ": hidden by " + filepath.Join(pwd, "testdata", "shadow", "root1", "src", "foo")
-	if strings.TrimSpace(tg.getStderr()) != want {
-		t.Error("wrong shadowed install error; looking for", want)
-	}
-}
-
-// Only succeeds if source order is preserved.
-func TestSourceFileNameOrderPreserved(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "testdata/example1_test.go", "testdata/example2_test.go")
-}
-
-// Check that coverage analysis works at all.
-// Don't worry about the exact numbers but require not 0.0%.
-func checkCoverage(tg *testgoData, data string) {
-	tg.t.Helper()
-	if regexp.MustCompile(`[^0-9]0\.0%`).MatchString(data) {
-		tg.t.Error("some coverage results are 0.0%")
-	}
-}
-
-func TestCoverageRuns(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no cover tool")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "-short", "-coverpkg=strings", "strings", "regexp")
-	data := tg.getStdout() + tg.getStderr()
-	tg.run("test", "-short", "-cover", "strings", "math", "regexp")
-	data += tg.getStdout() + tg.getStderr()
-	checkCoverage(tg, data)
-}
-
-func TestCoverageDotImport(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no cover tool")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.run("test", "-coverpkg=coverdot1,coverdot2", "coverdot2")
-	data := tg.getStdout() + tg.getStderr()
-	checkCoverage(tg, data)
-}
-
-func TestCoverageSyncAtomicImport(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no cover tool")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.run("test", "-short", "-cover", "-covermode=atomic", "-coverpkg=coverdep/p1", "coverdep")
-}
-
-func TestCoverageDepLoop(t *testing.T) {
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	// coverdep2/p1's xtest imports coverdep2/p2 which imports coverdep2/p1.
-	// Make sure that coverage on coverdep2/p2 recompiles coverdep2/p2.
-	tg.run("test", "-short", "-cover", "coverdep2/p1")
-	tg.grepStdout("coverage: 100.0% of statements", "expected 100.0% coverage")
-}
-
-func TestCoverageNoStatements(t *testing.T) {
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "-cover", "./testdata/testcover/pkg4")
-	tg.grepStdout("[no statements]", "expected [no statements] for pkg4")
-}
-
-func TestCoverageErrorLine(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no cover tool")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.setenv("GOTMPDIR", tg.tempdir)
-
-	tg.runFail("test", "coverbad")
-	tg.grepStderr(`coverbad[\\/]p\.go:4`, "did not find coverbad/p.go:4")
-	if canCgo {
-		tg.grepStderr(`coverbad[\\/]p1\.go:6`, "did not find coverbad/p1.go:6")
-	}
-	tg.grepStderrNot(regexp.QuoteMeta(tg.tempdir), "found temporary directory in error")
-	stderr := tg.getStderr()
-
-	tg.runFail("test", "-cover", "coverbad")
-	stderr2 := tg.getStderr()
-
-	// It's OK that stderr2 drops the character position in the error,
-	// because of the //line directive (see golang.org/issue/22662).
-	stderr = strings.ReplaceAll(stderr, "p.go:4:2:", "p.go:4:")
-	if stderr != stderr2 {
-		t.Logf("test -cover changed error messages:\nbefore:\n%s\n\nafter:\n%s", stderr, stderr2)
-		t.Skip("golang.org/issue/22660")
-		t.FailNow()
-	}
-}
-
-func TestTestBuildFailureOutput(t *testing.T) {
-	tooSlow(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-
-	// Doesn't build, -x output should not claim to run test.
-	tg.runFail("test", "-x", "coverbad")
-	tg.grepStderrNot(`[\\/]coverbad\.test( |$)`, "claimed to run test")
-}
-
-func TestCoverageFunc(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no cover tool")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-
-	tg.run("test", "-outputdir="+tg.tempdir, "-coverprofile=cover.out", "coverasm")
-	tg.run("tool", "cover", "-func="+tg.path("cover.out"))
-	tg.grepStdout(`\tg\t*100.0%`, "did not find g 100% covered")
-	tg.grepStdoutNot(`\tf\t*[0-9]`, "reported coverage for assembly function f")
-}
-
-// Issue 24588.
-func TestCoverageDashC(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no cover tool")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.run("test", "-c", "-o", tg.path("coverdep"), "-coverprofile="+tg.path("no/such/dir/cover.out"), "coverdep")
-	tg.wantExecutable(tg.path("coverdep"), "go -test -c -coverprofile did not create executable")
-}
-
-func TestTestEmpty(t *testing.T) {
-	if !canRace {
-		t.Skip("no race detector")
-	}
-
-	wd, _ := os.Getwd()
-	testdata := filepath.Join(wd, "testdata")
-	for _, dir := range []string{"pkg", "test", "xtest", "pkgtest", "pkgxtest", "pkgtestxtest", "testxtest"} {
-		t.Run(dir, func(t *testing.T) {
-			tg := testgo(t)
-			defer tg.cleanup()
-			tg.setenv("GOPATH", testdata)
-			tg.cd(filepath.Join(testdata, "src/empty/"+dir))
-			tg.run("test", "-cover", "-coverpkg=.", "-race")
-		})
-		if testing.Short() {
-			break
-		}
-	}
-}
-
-func TestNoGoError(t *testing.T) {
-	wd, _ := os.Getwd()
-	testdata := filepath.Join(wd, "testdata")
-	for _, dir := range []string{"empty/test", "empty/xtest", "empty/testxtest", "exclude", "exclude/ignore", "exclude/empty"} {
-		t.Run(dir, func(t *testing.T) {
-			tg := testgo(t)
-			defer tg.cleanup()
-			tg.setenv("GOPATH", testdata)
-			tg.cd(filepath.Join(testdata, "src"))
-			tg.runFail("build", "./"+dir)
-			var want string
-			if strings.Contains(dir, "test") {
-				want = "no non-test Go files in "
-			} else if dir == "exclude" {
-				want = "build constraints exclude all Go files in "
-			} else {
-				want = "no Go files in "
-			}
-			tg.grepStderr(want, "wrong reason for failure")
-		})
-	}
-}
-
-func TestTestRaceInstall(t *testing.T) {
-	if !canRace {
-		t.Skip("no race detector")
-	}
-	tooSlow(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-
-	tg.tempDir("pkg")
-	pkgdir := tg.path("pkg")
-	tg.run("install", "-race", "-pkgdir="+pkgdir, "std")
-	tg.run("test", "-race", "-pkgdir="+pkgdir, "-i", "-v", "empty/pkg")
-	if tg.getStderr() != "" {
-		t.Error("go test -i -race: rebuilds cached packages")
-	}
-}
-
-func TestBuildDryRunWithCgo(t *testing.T) {
-	if !canCgo {
-		t.Skip("skipping because cgo not enabled")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempFile("foo.go", `package main
-
-/*
-#include <limits.h>
-*/
-import "C"
-
-func main() {
-        println(C.INT_MAX)
-}`)
-	tg.run("build", "-n", tg.path("foo.go"))
-	tg.grepStderrNot(`os.Stat .* no such file or directory`, "unexpected stat of archive file")
-}
-
-func TestCgoDependsOnSyscall(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test that removes $GOROOT/pkg/*_race in short mode")
-	}
-	if !canCgo {
-		t.Skip("skipping because cgo not enabled")
-	}
-	if !canRace {
-		t.Skip("skipping because race detector not supported")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-
-	files, err := filepath.Glob(filepath.Join(runtime.GOROOT(), "pkg", "*_race"))
-	tg.must(err)
-	for _, file := range files {
-		tg.check(robustio.RemoveAll(file))
-	}
-	tg.tempFile("src/foo/foo.go", `
-		package foo
-		//#include <stdio.h>
-		import "C"`)
-	tg.setenv("GOPATH", tg.path("."))
-	tg.run("build", "-race", "foo")
-}
-
 func TestCgoShowsFullPathNames(t *testing.T) {
 	if !canCgo {
 		t.Skip("skipping because cgo not enabled")
@@ -2362,89 +1568,6 @@
 	tg.run("run", tg.path("foo.go"))
 }
 
-// "go test -c -test.bench=XXX errors" should not hang.
-// "go test -c" should also produce reproducible binaries.
-// "go test -c" should also appear to write a new binary every time,
-// even if it's really just updating the mtime on an existing up-to-date binary.
-func TestIssue6480(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no standard packages")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.makeTempdir()
-	tg.cd(tg.path("."))
-	tg.run("test", "-c", "-test.bench=XXX", "errors")
-	tg.run("test", "-c", "-o", "errors2.test", "errors")
-
-	data1, err := ioutil.ReadFile("errors.test" + exeSuffix)
-	tg.must(err)
-	data2, err := ioutil.ReadFile("errors2.test") // no exeSuffix because -o above doesn't have it
-	tg.must(err)
-	if !bytes.Equal(data1, data2) {
-		t.Fatalf("go test -c errors produced different binaries when run twice")
-	}
-
-	start := time.Now()
-	tg.run("test", "-x", "-c", "-test.bench=XXX", "errors")
-	tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary")
-	info, err := os.Stat("errors.test" + exeSuffix)
-	if err != nil {
-		t.Fatal(err)
-	}
-	start = truncateLike(start, info.ModTime())
-	if info.ModTime().Before(start) {
-		t.Fatalf("mtime of errors.test predates test -c command (%v < %v)", info.ModTime(), start)
-	}
-
-	start = time.Now()
-	tg.run("test", "-x", "-c", "-o", "errors2.test", "errors")
-	tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary")
-	info, err = os.Stat("errors2.test")
-	if err != nil {
-		t.Fatal(err)
-	}
-	start = truncateLike(start, info.ModTime())
-	if info.ModTime().Before(start) {
-		t.Fatalf("mtime of errors2.test predates test -c command (%v < %v)", info.ModTime(), start)
-	}
-}
-
-// truncateLike returns the result of truncating t to the apparent precision of p.
-func truncateLike(t, p time.Time) time.Time {
-	nano := p.UnixNano()
-	d := 1 * time.Nanosecond
-	for nano%int64(d) == 0 && d < 1*time.Second {
-		d *= 10
-	}
-	for nano%int64(d) == 0 && d < 2*time.Second {
-		d *= 2
-	}
-	return t.Truncate(d)
-}
-
-// cmd/cgo: undefined reference when linking a C-library using gccgo
-func TestIssue7573(t *testing.T) {
-	if !canCgo {
-		t.Skip("skipping because cgo not enabled")
-	}
-	testenv.MustHaveExecPath(t, "gccgo")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.tempFile("src/cgoref/cgoref.go", `
-package main
-// #cgo LDFLAGS: -L alibpath -lalib
-// void f(void) {}
-import "C"
-
-func main() { C.f() }`)
-	tg.setenv("GOPATH", tg.path("."))
-	tg.run("build", "-n", "-compiler", "gccgo", "cgoref")
-	tg.grepStderr(`gccgo.*\-L [^ ]*alibpath \-lalib`, `no Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage`)
-}
-
 func TestListTemplateContextFunction(t *testing.T) {
 	t.Parallel()
 	for _, tt := range []struct {
@@ -2479,242 +1602,6 @@
 	}
 }
 
-func TestGoBuildTestOnly(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-	tg.tempFile("src/testonly/t_test.go", `package testonly`)
-	tg.tempFile("src/testonly2/t.go", `package testonly2`)
-	tg.cd(tg.path("src"))
-
-	// Named explicitly, test-only packages should be reported as unbuildable/uninstallable,
-	// even if there is a wildcard also matching.
-	tg.runFail("build", "testonly", "testonly...")
-	tg.grepStderr("no non-test Go files in", "go build ./xtestonly produced unexpected error")
-	tg.runFail("install", "./testonly")
-	tg.grepStderr("no non-test Go files in", "go install ./testonly produced unexpected error")
-
-	// Named through a wildcards, the test-only packages should be silently ignored.
-	tg.run("build", "testonly...")
-	tg.run("install", "./testonly...")
-}
-
-func TestGoTestFooTestWorks(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "testdata/standalone_test.go")
-}
-
-func TestGoTestTestMainSeesTestingFlags(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "testdata/standalone_testmain_flag_test.go")
-}
-
-// Issue 22388
-func TestGoTestMainWithWrongSignature(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.runFail("test", "testdata/standalone_main_wrong_test.go")
-	tg.grepStderr(`wrong signature for TestMain, must be: func TestMain\(m \*testing.M\)`, "detected wrong error message")
-}
-
-func TestGoTestMainAsNormalTest(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "testdata/standalone_main_normal_test.go")
-	tg.grepBoth(okPattern, "go test did not say ok")
-}
-
-func TestGoTestXtestonlyWorks(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.run("clean", "-i", "xtestonly")
-	tg.run("test", "xtestonly")
-}
-
-func TestGoTestBuildsAnXtestContainingOnlyNonRunnableExamples(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "-v", "./testdata/norunexample")
-	tg.grepStdout("File with non-runnable example was built.", "file with non-runnable example was not built")
-}
-
-func TestGoGenerateHandlesSimpleCommand(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("skipping because windows has no echo command")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("generate", "./testdata/generate/test1.go")
-	tg.grepStdout("Success", "go generate ./testdata/generate/test1.go generated wrong output")
-}
-
-func TestGoGenerateHandlesCommandAlias(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("skipping because windows has no echo command")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("generate", "./testdata/generate/test2.go")
-	tg.grepStdout("Now is the time for all good men", "go generate ./testdata/generate/test2.go generated wrong output")
-}
-
-func TestGoGenerateVariableSubstitution(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("skipping because windows has no echo command")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("generate", "./testdata/generate/test3.go")
-	tg.grepStdout(runtime.GOARCH+" test3.go:7 pabc xyzp/test3.go/123", "go generate ./testdata/generate/test3.go generated wrong output")
-}
-
-func TestGoGenerateRunFlag(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("skipping because windows has no echo command")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("generate", "-run", "y.s", "./testdata/generate/test4.go")
-	tg.grepStdout("yes", "go generate -run yes ./testdata/generate/test4.go did not select yes")
-	tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no")
-}
-
-func TestGoGenerateEnv(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9", "windows":
-		t.Skipf("skipping because %s does not have the env command", runtime.GOOS)
-	}
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.tempFile("env.go", "package main\n\n//go:generate env")
-	tg.run("generate", tg.path("env.go"))
-	for _, v := range []string{"GOARCH", "GOOS", "GOFILE", "GOLINE", "GOPACKAGE", "DOLLAR"} {
-		tg.grepStdout("^"+v+"=", "go generate environment missing "+v)
-	}
-}
-
-func TestGoGenerateXTestPkgName(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("skipping because windows has no echo command")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.tempFile("env_test.go", "package main_test\n\n//go:generate echo $GOPACKAGE")
-	tg.run("generate", tg.path("env_test.go"))
-	want := "main_test"
-	if got := strings.TrimSpace(tg.getStdout()); got != want {
-		t.Errorf("go generate in XTest file got package name %q; want %q", got, want)
-	}
-}
-
-func TestGoGetCustomDomainWildcard(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-	tg.run("get", "-u", "rsc.io/pdf/...")
-	tg.wantExecutable(tg.path("bin/pdfpasswd"+exeSuffix), "did not build rsc/io/pdf/pdfpasswd")
-}
-
-func TestGoGetInternalWildcard(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-	// used to fail with errors about internal packages
-	tg.run("get", "github.com/rsc/go-get-issue-11960/...")
-}
-
-func TestGoVetWithExternalTests(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.runFail("vet", "vetpkg")
-	tg.grepBoth("Printf", "go vet vetpkg did not find missing argument for Printf")
-}
-
-func TestGoVetWithTags(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.runFail("vet", "-tags", "tagtest", "vetpkg")
-	tg.grepBoth(`c\.go.*Printf`, "go vet vetpkg did not run scan tagged file")
-}
-
-func TestGoVetWithFlagsOn(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.runFail("vet", "-printf", "vetpkg")
-	tg.grepBoth("Printf", "go vet -printf vetpkg did not find missing argument for Printf")
-}
-
-func TestGoVetWithFlagsOff(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.run("vet", "-printf=false", "vetpkg")
-}
-
-// Issue 23395.
-func TestGoVetWithOnlyTestFiles(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.tempFile("src/p/p_test.go", "package p; import \"testing\"; func TestMe(*testing.T) {}")
-	tg.setenv("GOPATH", tg.path("."))
-	tg.run("vet", "p")
-}
-
-// Issue 24193.
-func TestVetWithOnlyCgoFiles(t *testing.T) {
-	if !canCgo {
-		t.Skip("skipping because cgo not enabled")
-	}
-	tooSlow(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.tempFile("src/p/p.go", "package p; import \"C\"; func F() {}")
-	tg.setenv("GOPATH", tg.path("."))
-	tg.run("vet", "p")
-}
-
-// Issue 9767, 19769.
-func TestGoGetDotSlashDownload(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempDir("src/rsc.io")
-	tg.setenv("GOPATH", tg.path("."))
-	tg.cd(tg.path("src/rsc.io"))
-	tg.run("get", "./pprof_mac_fix")
-}
-
 // Test that you cannot use a local import in a package
 // accessed by a non-local import (found in a GOPATH/GOROOT).
 // See golang.org/issue/17475.
@@ -2869,132 +1756,6 @@
 	tg.grepStderr("cannot import current directory", "did not diagnose import current directory")
 }
 
-func TestGoGetInsecure(t *testing.T) {
-	test := func(t *testing.T, modules bool) {
-		testenv.MustHaveExternalNetwork(t)
-		testenv.MustHaveExecPath(t, "git")
-
-		tg := testgo(t)
-		defer tg.cleanup()
-		tg.makeTempdir()
-		tg.failSSH()
-
-		if modules {
-			tg.setenv("GOPATH", tg.path("gp"))
-			tg.tempFile("go.mod", "module m")
-			tg.cd(tg.path("."))
-			tg.setenv("GO111MODULE", "on")
-			tg.setenv("GOPROXY", "")
-		} else {
-			tg.setenv("GOPATH", tg.path("."))
-			tg.setenv("GO111MODULE", "off")
-		}
-
-		const repo = "insecure.go-get-issue-15410.appspot.com/pkg/p"
-
-		// Try go get -d of HTTP-only repo (should fail).
-		tg.runFail("get", "-d", repo)
-
-		// Try again with -insecure (should succeed).
-		tg.run("get", "-d", "-insecure", repo)
-
-		// Try updating without -insecure (should fail).
-		tg.runFail("get", "-d", "-u", "-f", repo)
-
-		if modules {
-			tg.run("list", "-m", "...")
-			tg.grepStdout("insecure.go-get-issue", "should find insecure module")
-		}
-	}
-
-	t.Run("gopath", func(t *testing.T) { test(t, false) })
-	t.Run("modules", func(t *testing.T) { test(t, true) })
-}
-
-func TestGoGetUpdateInsecure(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-
-	const repo = "github.com/golang/example"
-
-	// Clone the repo via HTTP manually.
-	cmd := exec.Command("git", "clone", "-q", "http://"+repo, tg.path("src/"+repo))
-	if out, err := cmd.CombinedOutput(); err != nil {
-		t.Fatalf("cloning %v repo: %v\n%s", repo, err, out)
-	}
-
-	// Update without -insecure should fail.
-	// Update with -insecure should succeed.
-	// We need -f to ignore import comments.
-	const pkg = repo + "/hello"
-	tg.runFail("get", "-d", "-u", "-f", pkg)
-	tg.run("get", "-d", "-u", "-f", "-insecure", pkg)
-}
-
-func TestGoGetUpdateUnknownProtocol(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-
-	const repo = "github.com/golang/example"
-
-	// Clone the repo via HTTPS manually.
-	repoDir := tg.path("src/" + repo)
-	cmd := exec.Command("git", "clone", "-q", "https://"+repo, repoDir)
-	if out, err := cmd.CombinedOutput(); err != nil {
-		t.Fatalf("cloning %v repo: %v\n%s", repo, err, out)
-	}
-
-	// Configure the repo to use a protocol unknown to cmd/go
-	// that still actually works.
-	cmd = exec.Command("git", "remote", "set-url", "origin", "xyz://"+repo)
-	cmd.Dir = repoDir
-	if out, err := cmd.CombinedOutput(); err != nil {
-		t.Fatalf("git remote set-url: %v\n%s", err, out)
-	}
-	cmd = exec.Command("git", "config", "--local", "url.https://github.com/.insteadOf", "xyz://github.com/")
-	cmd.Dir = repoDir
-	if out, err := cmd.CombinedOutput(); err != nil {
-		t.Fatalf("git config: %v\n%s", err, out)
-	}
-
-	// We need -f to ignore import comments.
-	tg.run("get", "-d", "-u", "-f", repo+"/hello")
-}
-
-func TestGoGetInsecureCustomDomain(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-
-	const repo = "insecure.go-get-issue-15410.appspot.com/pkg/p"
-	tg.runFail("get", "-d", repo)
-	tg.run("get", "-d", "-insecure", repo)
-}
-
-func TestGoRunDirs(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.cd("testdata/rundir")
-	tg.runFail("run", "x.go", "sub/sub.go")
-	tg.grepStderr("named files must all be in one directory; have ./ and sub/", "wrong output")
-	tg.runFail("run", "sub/sub.go", "x.go")
-	tg.grepStderr("named files must all be in one directory; have sub/ and ./", "wrong output")
-}
-
 func TestGoInstallPkgdir(t *testing.T) {
 	skipIfGccgo(t, "gccgo has no standard packages")
 	tooSlow(t)
@@ -3012,294 +1773,6 @@
 	tg.mustExist(filepath.Join(pkg, "sync/atomic.a"))
 }
 
-func TestGoTestRaceInstallCgo(t *testing.T) {
-	if !canRace {
-		t.Skip("skipping because race detector not supported")
-	}
-
-	// golang.org/issue/10500.
-	// This used to install a race-enabled cgo.
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("tool", "-n", "cgo")
-	cgo := strings.TrimSpace(tg.stdout.String())
-	old, err := os.Stat(cgo)
-	tg.must(err)
-
-	// For this test, we don't actually care whether 'go test -race -i' succeeds.
-	// It may fail, for example, if GOROOT was installed from source as root and
-	// is now read-only.
-	// We only care that — regardless of whether it succeeds — it does not
-	// overwrite cmd/cgo.
-	runArgs := []string{"test", "-race", "-i", "runtime/race"}
-	if status := tg.doRun(runArgs); status != nil {
-		tg.t.Logf("go %v failure ignored: %v", runArgs, status)
-	}
-
-	new, err := os.Stat(cgo)
-	tg.must(err)
-	if !new.ModTime().Equal(old.ModTime()) {
-		t.Fatalf("go test -i runtime/race reinstalled cmd/cgo")
-	}
-}
-
-func TestGoGetUpdate(t *testing.T) {
-	// golang.org/issue/9224.
-	// The recursive updating was trying to walk to
-	// former dependencies, not current ones.
-
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-
-	rewind := func() {
-		tg.run("get", "github.com/rsc/go-get-issue-9224-cmd")
-		cmd := exec.Command("git", "reset", "--hard", "HEAD~")
-		cmd.Dir = tg.path("src/github.com/rsc/go-get-issue-9224-lib")
-		out, err := cmd.CombinedOutput()
-		if err != nil {
-			t.Fatalf("git: %v\n%s", err, out)
-		}
-	}
-
-	rewind()
-	tg.run("get", "-u", "github.com/rsc/go-get-issue-9224-cmd")
-
-	// Again with -d -u.
-	rewind()
-	tg.run("get", "-d", "-u", "github.com/rsc/go-get-issue-9224-cmd")
-}
-
-// Issue #20512.
-func TestGoGetRace(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-	if !canRace {
-		t.Skip("skipping because race detector not supported")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-	tg.run("get", "-race", "github.com/rsc/go-get-issue-9224-cmd")
-}
-
-func TestGoGetDomainRoot(t *testing.T) {
-	// golang.org/issue/9357.
-	// go get foo.io (not foo.io/subdir) was not working consistently.
-
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-
-	// go-get-issue-9357.appspot.com is running
-	// the code at github.com/rsc/go-get-issue-9357,
-	// a trivial Go on App Engine app that serves a
-	// <meta> tag for the domain root.
-	tg.run("get", "-d", "go-get-issue-9357.appspot.com")
-	tg.run("get", "go-get-issue-9357.appspot.com")
-	tg.run("get", "-u", "go-get-issue-9357.appspot.com")
-
-	tg.must(robustio.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com")))
-	tg.run("get", "go-get-issue-9357.appspot.com")
-
-	tg.must(robustio.RemoveAll(tg.path("src/go-get-issue-9357.appspot.com")))
-	tg.run("get", "-u", "go-get-issue-9357.appspot.com")
-}
-
-func TestGoInstallShadowedGOPATH(t *testing.T) {
-	// golang.org/issue/3652.
-	// go get foo.io (not foo.io/subdir) was not working consistently.
-
-	testenv.MustHaveExternalNetwork(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("gopath1")+string(filepath.ListSeparator)+tg.path("gopath2"))
-
-	tg.tempDir("gopath1/src/test")
-	tg.tempDir("gopath2/src/test")
-	tg.tempFile("gopath2/src/test/main.go", "package main\nfunc main(){}\n")
-
-	tg.cd(tg.path("gopath2/src/test"))
-	tg.runFail("install")
-	tg.grepStderr("no install location for.*gopath2.src.test: hidden by .*gopath1.src.test", "missing error")
-}
-
-func TestGoBuildGOPATHOrder(t *testing.T) {
-	// golang.org/issue/14176#issuecomment-179895769
-	// golang.org/issue/14192
-	// -I arguments to compiler could end up not in GOPATH order,
-	// leading to unexpected import resolution in the compiler.
-	// This is still not a complete fix (see golang.org/issue/14271 and next test)
-	// but it is clearly OK and enough to fix both of the two reported
-	// instances of the underlying problem. It will have to do for now.
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("p1")+string(filepath.ListSeparator)+tg.path("p2"))
-
-	tg.tempFile("p1/src/foo/foo.go", "package foo\n")
-	tg.tempFile("p2/src/baz/baz.go", "package baz\n")
-	tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n")
-	tg.tempFile("p1/src/bar/bar.go", `
-		package bar
-		import _ "baz"
-		import _ "foo"
-	`)
-
-	tg.run("install", "-x", "bar")
-}
-
-func TestGoBuildGOPATHOrderBroken(t *testing.T) {
-	// This test is known not to work.
-	// See golang.org/issue/14271.
-	t.Skip("golang.org/issue/14271")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-
-	tg.tempFile("p1/src/foo/foo.go", "package foo\n")
-	tg.tempFile("p2/src/baz/baz.go", "package baz\n")
-	tg.tempFile("p1/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/baz.a", "bad\n")
-	tg.tempFile("p2/pkg/"+runtime.GOOS+"_"+runtime.GOARCH+"/foo.a", "bad\n")
-	tg.tempFile("p1/src/bar/bar.go", `
-		package bar
-		import _ "baz"
-		import _ "foo"
-	`)
-
-	colon := string(filepath.ListSeparator)
-	tg.setenv("GOPATH", tg.path("p1")+colon+tg.path("p2"))
-	tg.run("install", "-x", "bar")
-
-	tg.setenv("GOPATH", tg.path("p2")+colon+tg.path("p1"))
-	tg.run("install", "-x", "bar")
-}
-
-func TestIssue11709(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempFile("run.go", `
-		package main
-		import "os"
-		func main() {
-			if os.Getenv("TERM") != "" {
-				os.Exit(1)
-			}
-		}`)
-	tg.unsetenv("TERM")
-	tg.run("run", tg.path("run.go"))
-}
-
-func TestIssue12096(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempFile("test_test.go", `
-		package main
-		import ("os"; "testing")
-		func TestEnv(t *testing.T) {
-			if os.Getenv("TERM") != "" {
-				t.Fatal("TERM is set")
-			}
-		}`)
-	tg.unsetenv("TERM")
-	tg.run("test", tg.path("test_test.go"))
-}
-
-func TestGoBuildOutput(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no standard packages")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	tg.makeTempdir()
-	tg.cd(tg.path("."))
-
-	nonExeSuffix := ".exe"
-	if exeSuffix == ".exe" {
-		nonExeSuffix = ""
-	}
-
-	tg.tempFile("x.go", "package main\nfunc main(){}\n")
-	tg.run("build", "x.go")
-	tg.wantExecutable("x"+exeSuffix, "go build x.go did not write x"+exeSuffix)
-	tg.must(os.Remove(tg.path("x" + exeSuffix)))
-	tg.mustNotExist("x" + nonExeSuffix)
-
-	tg.run("build", "-o", "myprog", "x.go")
-	tg.mustNotExist("x")
-	tg.mustNotExist("x.exe")
-	tg.wantExecutable("myprog", "go build -o myprog x.go did not write myprog")
-	tg.mustNotExist("myprog.exe")
-
-	tg.tempFile("p.go", "package p\n")
-	tg.run("build", "p.go")
-	tg.mustNotExist("p")
-	tg.mustNotExist("p.a")
-	tg.mustNotExist("p.o")
-	tg.mustNotExist("p.exe")
-
-	tg.run("build", "-o", "p.a", "p.go")
-	tg.wantArchive("p.a")
-
-	tg.run("build", "cmd/gofmt")
-	tg.wantExecutable("gofmt"+exeSuffix, "go build cmd/gofmt did not write gofmt"+exeSuffix)
-	tg.must(os.Remove(tg.path("gofmt" + exeSuffix)))
-	tg.mustNotExist("gofmt" + nonExeSuffix)
-
-	tg.run("build", "-o", "mygofmt", "cmd/gofmt")
-	tg.wantExecutable("mygofmt", "go build -o mygofmt cmd/gofmt did not write mygofmt")
-	tg.mustNotExist("mygofmt.exe")
-	tg.mustNotExist("gofmt")
-	tg.mustNotExist("gofmt.exe")
-
-	tg.run("build", "sync/atomic")
-	tg.mustNotExist("atomic")
-	tg.mustNotExist("atomic.exe")
-
-	tg.run("build", "-o", "myatomic.a", "sync/atomic")
-	tg.wantArchive("myatomic.a")
-	tg.mustNotExist("atomic")
-	tg.mustNotExist("atomic.a")
-	tg.mustNotExist("atomic.exe")
-
-	tg.runFail("build", "-o", "whatever", "cmd/gofmt", "sync/atomic")
-	tg.grepStderr("multiple packages", "did not reject -o with multiple packages")
-}
-
-func TestGoBuildARM(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping cross-compile in short mode")
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	tg.makeTempdir()
-	tg.cd(tg.path("."))
-
-	tg.setenv("GOARCH", "arm")
-	tg.setenv("GOOS", "linux")
-	tg.setenv("GOARM", "5")
-	tg.tempFile("hello.go", `package main
-		func main() {}`)
-	tg.run("build", "hello.go")
-	tg.grepStderrNot("unable to find math.a", "did not build math.a correctly")
-}
-
 // For issue 14337.
 func TestParallelTest(t *testing.T) {
 	tooSlow(t)
@@ -3321,50 +1794,6 @@
 	tg.run("test", "-p=4", "p1", "p2", "p3", "p4")
 }
 
-func TestCgoConsistentResults(t *testing.T) {
-	tooSlow(t)
-	if !canCgo {
-		t.Skip("skipping because cgo not enabled")
-	}
-	switch runtime.GOOS {
-	case "solaris", "illumos":
-		testenv.SkipFlaky(t, 13247)
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	exe1 := tg.path("cgotest1" + exeSuffix)
-	exe2 := tg.path("cgotest2" + exeSuffix)
-	tg.run("build", "-o", exe1, "cgotest")
-	tg.run("build", "-x", "-o", exe2, "cgotest")
-	b1, err := ioutil.ReadFile(exe1)
-	tg.must(err)
-	b2, err := ioutil.ReadFile(exe2)
-	tg.must(err)
-
-	if !tg.doGrepMatch(`-fdebug-prefix-map=\$WORK`, &tg.stderr) {
-		t.Skip("skipping because C compiler does not support -fdebug-prefix-map")
-	}
-	if !bytes.Equal(b1, b2) {
-		t.Error("building cgotest twice did not produce the same output")
-	}
-}
-
-// Issue 14444: go get -u .../ duplicate loads errors
-func TestGoGetUpdateAllDoesNotTryToLoadDuplicates(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-	tg.run("get", "-u", ".../")
-	tg.grepStderrNot("duplicate loads of", "did not remove old packages from cache")
-}
-
 func TestBinaryOnlyPackages(t *testing.T) {
 	tooSlow(t)
 
@@ -3456,39 +1885,9 @@
 	tg.grepStdout("linux amd64", "unexpected GOOS/GOARCH combination")
 
 	tg.setenv("GOOS", "darwin")
-	tg.setenv("GOARCH", "386")
+	tg.setenv("GOARCH", "arm64")
 	tg.run("generate", "gen")
-	tg.grepStdout("darwin 386", "unexpected GOOS/GOARCH combination")
-}
-
-// Issue 14450: go get -u .../ tried to import not downloaded package
-func TestGoGetUpdateWithWildcard(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("."))
-	const aPkgImportPath = "github.com/tmwh/go-get-issue-14450/a"
-	tg.run("get", aPkgImportPath)
-	tg.runFail("get", "-u", ".../")
-	tg.grepStderr("cannot find package.*d-dependency/e", "should have detected e missing")
-
-	// Even though get -u failed, the source for others should be downloaded.
-	var expectedPkgPaths = []string{
-		"src/github.com/tmwh/go-get-issue-14450/b",
-		"src/github.com/tmwh/go-get-issue-14450-b-dependency/c",
-		"src/github.com/tmwh/go-get-issue-14450-b-dependency/d",
-	}
-
-	for _, importPath := range expectedPkgPaths {
-		_, err := os.Stat(tg.path(importPath))
-		tg.must(err)
-	}
-	const notExpectedPkgPath = "src/github.com/tmwh/go-get-issue-14450-c-dependency/e"
-	tg.mustNotExist(tg.path(notExpectedPkgPath))
+	tg.grepStdout("darwin arm64", "unexpected GOOS/GOARCH combination")
 }
 
 func TestGoEnv(t *testing.T) {
@@ -3522,153 +1921,6 @@
 	okPattern        = `(?m)^ok`
 )
 
-func TestMatchesNoTests(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.run("test", "-run", "ThisWillNotMatch", "testdata/standalone_test.go")
-	tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]")
-}
-
-func TestMatchesNoBenchmarksIsOK(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.run("test", "-run", "^$", "-bench", "ThisWillNotMatch", "testdata/standalone_benchmark_test.go")
-	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
-	tg.grepBoth(okPattern, "go test did not say ok")
-}
-
-func TestMatchesOnlyExampleIsOK(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.run("test", "-run", "Example", "testdata/example1_test.go")
-	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
-	tg.grepBoth(okPattern, "go test did not say ok")
-}
-
-func TestMatchesOnlyBenchmarkIsOK(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.run("test", "-run", "^$", "-bench", ".", "testdata/standalone_benchmark_test.go")
-	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
-	tg.grepBoth(okPattern, "go test did not say ok")
-}
-
-func TestBenchmarkLabelsOutsideGOPATH(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.run("test", "-run", "^$", "-bench", ".", "testdata/standalone_benchmark_test.go")
-	tg.grepStdout(`(?m)^goos: `+runtime.GOOS, "go test did not print goos")
-	tg.grepStdout(`(?m)^goarch: `+runtime.GOARCH, "go test did not print goarch")
-	tg.grepBothNot(`(?m)^pkg:`, "go test did say pkg:")
-}
-
-func TestMatchesOnlyTestIsOK(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	// TODO: tg.parallel()
-	tg.run("test", "-run", "Test", "testdata/standalone_test.go")
-	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
-	tg.grepBoth(okPattern, "go test did not say ok")
-}
-
-func TestMatchesNoTestsWithSubtests(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "-run", "ThisWillNotMatch", "testdata/standalone_sub_test.go")
-	tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]")
-}
-
-func TestMatchesNoSubtestsMatch(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "-run", "Test/ThisWillNotMatch", "testdata/standalone_sub_test.go")
-	tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]")
-}
-
-func TestMatchesNoSubtestsDoesNotOverrideFailure(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.runFail("test", "-run", "TestThatFails/ThisWillNotMatch", "testdata/standalone_fail_sub_test.go")
-	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
-	tg.grepBoth("FAIL", "go test did not say FAIL")
-}
-
-func TestMatchesOnlySubtestIsOK(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "-run", "Test/Sub", "testdata/standalone_sub_test.go")
-	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
-	tg.grepBoth(okPattern, "go test did not say ok")
-}
-
-func TestMatchesNoSubtestsParallel(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "-run", "Test/Sub/ThisWillNotMatch", "testdata/standalone_parallel_sub_test.go")
-	tg.grepBoth(noMatchesPattern, "go test did not say [no tests to run]")
-}
-
-func TestMatchesOnlySubtestParallelIsOK(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "-run", "Test/Sub/Nested", "testdata/standalone_parallel_sub_test.go")
-	tg.grepBothNot(noMatchesPattern, "go test did say [no tests to run]")
-	tg.grepBoth(okPattern, "go test did not say ok")
-}
-
-// Issue 18845
-func TestBenchTimeout(t *testing.T) {
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.run("test", "-bench", ".", "-timeout", "750ms", "testdata/timeoutbench_test.go")
-}
-
-// Issue 19394
-func TestWriteProfilesOnTimeout(t *testing.T) {
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.tempDir("profiling")
-	tg.tempFile("profiling/timeouttest_test.go", `package timeouttest_test
-import "testing"
-import "time"
-func TestSleep(t *testing.T) { time.Sleep(time.Second) }`)
-	tg.cd(tg.path("profiling"))
-	tg.runFail(
-		"test",
-		"-cpuprofile", tg.path("profiling/cpu.pprof"), "-memprofile", tg.path("profiling/mem.pprof"),
-		"-timeout", "1ms")
-	tg.mustHaveContent(tg.path("profiling/cpu.pprof"))
-	tg.mustHaveContent(tg.path("profiling/mem.pprof"))
-}
-
-func TestLinkXImportPathEscape(t *testing.T) {
-	// golang.org/issue/16710
-	skipIfGccgo(t, "gccgo does not support -ldflags -X")
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	exe := tg.path("linkx" + exeSuffix)
-	tg.creatingTemp(exe)
-	tg.run("build", "-o", exe, "-ldflags", "-X=my.pkg.Text=linkXworked", "my.pkg/main")
-	out, err := exec.Command(exe).CombinedOutput()
-	if err != nil {
-		tg.t.Fatal(err)
-	}
-	if string(out) != "linkXworked\n" {
-		tg.t.Log(string(out))
-		tg.t.Fatal(`incorrect output: expected "linkXworked\n"`)
-	}
-}
-
 // Issue 18044.
 func TestLdBindNow(t *testing.T) {
 	tg := testgo(t)
@@ -3695,29 +1947,6 @@
 	tg.run("build", "p")
 }
 
-// Issue 18778.
-func TestDotDotDotOutsideGOPATH(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	tg.tempFile("pkgs/a.go", `package x`)
-	tg.tempFile("pkgs/a_test.go", `package x_test
-import "testing"
-func TestX(t *testing.T) {}`)
-
-	tg.tempFile("pkgs/a/a.go", `package a`)
-	tg.tempFile("pkgs/a/a_test.go", `package a_test
-import "testing"
-func TestA(t *testing.T) {}`)
-
-	tg.cd(tg.path("pkgs"))
-	tg.run("build", "./...")
-	tg.run("test", "./...")
-	tg.run("list", "./...")
-	tg.grepStdout("pkgs$", "expected package not listed")
-	tg.grepStdout("pkgs/a", "expected package not listed")
-}
-
 // Issue 18975.
 func TestFFLAGS(t *testing.T) {
 	if !canCgo {
@@ -3790,17 +2019,6 @@
 	tg.run("build", "-o", exe, "p")
 }
 
-func TestBuildTagsNoComma(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no standard packages")
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.makeTempdir()
-	tg.setenv("GOPATH", tg.path("go"))
-	tg.run("build", "-tags", "tag1 tag2", "math")
-	tg.runFail("build", "-tags", "tag1,tag2 tag3", "math")
-	tg.grepBoth("space-separated list contains comma", "-tags with a comma-separated list didn't error")
-}
-
 func copyFile(src, dst string, perm os.FileMode) error {
 	sf, err := os.Open(src)
 	if err != nil {
@@ -3821,106 +2039,6 @@
 	return err2
 }
 
-// TestExecutableGOROOT verifies that the cmd/go binary itself uses
-// os.Executable (when available) to locate GOROOT.
-func TestExecutableGOROOT(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no GOROOT")
-
-	// Note: Must not call tg methods inside subtests: tg is attached to outer t.
-	tg := testgo(t)
-	tg.unsetenv("GOROOT")
-	defer tg.cleanup()
-
-	check := func(t *testing.T, exe, want string) {
-		cmd := exec.Command(exe, "env", "GOROOT")
-		cmd.Env = tg.env
-		out, err := cmd.CombinedOutput()
-		if err != nil {
-			t.Fatalf("%s env GOROOT: %v, %s", exe, err, out)
-		}
-		goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out)))
-		if err != nil {
-			t.Fatal(err)
-		}
-		want, err = filepath.EvalSymlinks(want)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if !strings.EqualFold(goroot, want) {
-			t.Errorf("go env GOROOT:\nhave %s\nwant %s", goroot, want)
-		} else {
-			t.Logf("go env GOROOT: %s", goroot)
-		}
-	}
-
-	tg.makeTempdir()
-	tg.tempDir("new/bin")
-	newGoTool := tg.path("new/bin/go" + exeSuffix)
-	tg.must(copyFile(tg.goTool(), newGoTool, 0775))
-	newRoot := tg.path("new")
-
-	t.Run("RelocatedExe", func(t *testing.T) {
-		// Should fall back to default location in binary,
-		// which is the GOROOT we used when building testgo.exe.
-		check(t, newGoTool, testGOROOT)
-	})
-
-	// If the binary is sitting in a bin dir next to ../pkg/tool, that counts as a GOROOT,
-	// so it should find the new tree.
-	tg.tempDir("new/pkg/tool")
-	t.Run("RelocatedTree", func(t *testing.T) {
-		check(t, newGoTool, newRoot)
-	})
-
-	tg.tempDir("other/bin")
-	symGoTool := tg.path("other/bin/go" + exeSuffix)
-
-	// Symlink into go tree should still find go tree.
-	t.Run("SymlinkedExe", func(t *testing.T) {
-		testenv.MustHaveSymlink(t)
-		if err := os.Symlink(newGoTool, symGoTool); err != nil {
-			t.Fatal(err)
-		}
-		check(t, symGoTool, newRoot)
-	})
-
-	tg.must(robustio.RemoveAll(tg.path("new/pkg")))
-
-	// Binaries built in the new tree should report the
-	// new tree when they call runtime.GOROOT.
-	t.Run("RuntimeGoroot", func(t *testing.T) {
-		// Build a working GOROOT the easy way, with symlinks.
-		testenv.MustHaveSymlink(t)
-		if err := os.Symlink(filepath.Join(testGOROOT, "src"), tg.path("new/src")); err != nil {
-			t.Fatal(err)
-		}
-		if err := os.Symlink(filepath.Join(testGOROOT, "pkg"), tg.path("new/pkg")); err != nil {
-			t.Fatal(err)
-		}
-
-		cmd := exec.Command(newGoTool, "run", "testdata/print_goroot.go")
-		cmd.Env = tg.env
-		cmd.Stderr = os.Stderr
-		out, err := cmd.Output()
-		if err != nil {
-			t.Fatalf("%s run testdata/print_goroot.go: %v, %s", newGoTool, err, out)
-		}
-		goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out)))
-		if err != nil {
-			t.Fatal(err)
-		}
-		want, err := filepath.EvalSymlinks(tg.path("new"))
-		if err != nil {
-			t.Fatal(err)
-		}
-		if !strings.EqualFold(goroot, want) {
-			t.Errorf("go run testdata/print_goroot.go:\nhave %s\nwant %s", goroot, want)
-		} else {
-			t.Logf("go run testdata/print_goroot.go: %s", goroot)
-		}
-	})
-}
-
 func TestNeedVersion(t *testing.T) {
 	skipIfGccgo(t, "gccgo does not use cmd/compile")
 	tg := testgo(t)
@@ -3933,47 +2051,6 @@
 	tg.grepStderr("compile", "does not match go tool version")
 }
 
-func TestCgoFlagContainsSpace(t *testing.T) {
-	tooSlow(t)
-	if !canCgo {
-		t.Skip("skipping because cgo not enabled")
-	}
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	tg.makeTempdir()
-	tg.cd(tg.path("."))
-	tg.tempFile("main.go", `package main
-		// #cgo CFLAGS: -I"c flags"
-		// #cgo LDFLAGS: -L"ld flags"
-		import "C"
-		func main() {}
-	`)
-	tg.run("run", "-x", "main.go")
-	tg.grepStderr(`"-I[^"]+c flags"`, "did not find quoted c flags")
-	tg.grepStderrNot(`"-I[^"]+c flags".*"-I[^"]+c flags"`, "found too many quoted c flags")
-	tg.grepStderr(`"-L[^"]+ld flags"`, "did not find quoted ld flags")
-	tg.grepStderrNot(`"-L[^"]+c flags".*"-L[^"]+c flags"`, "found too many quoted ld flags")
-}
-
-func TestListTests(t *testing.T) {
-	tooSlow(t)
-	var tg *testgoData
-	testWith := func(listName, expected string) func(*testing.T) {
-		return func(t *testing.T) {
-			tg = testgo(t)
-			defer tg.cleanup()
-			tg.run("test", "./testdata/src/testlist/...", fmt.Sprintf("-list=%s", listName))
-			tg.grepStdout(expected, fmt.Sprintf("-test.list=%s returned %q, expected %s", listName, tg.getStdout(), expected))
-		}
-	}
-
-	t.Run("Test", testWith("Test", "TestSimple"))
-	t.Run("Bench", testWith("Benchmark", "BenchmarkSimple"))
-	t.Run("Example1", testWith("Example", "ExampleSimple"))
-	t.Run("Example2", testWith("Example", "ExampleWithEmptyOutput"))
-}
-
 func TestBuildmodePIE(t *testing.T) {
 	if testing.Short() && testenv.Builder() == "" {
 		t.Skipf("skipping in -short mode on non-builder")
@@ -3983,20 +2060,62 @@
 	switch platform {
 	case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
 		"android/amd64", "android/arm", "android/arm64", "android/386",
-		"freebsd/amd64":
+		"freebsd/amd64",
+		"windows/386", "windows/amd64", "windows/arm":
 	case "darwin/amd64":
 	default:
 		t.Skipf("skipping test because buildmode=pie is not supported on %s", platform)
 	}
+	t.Run("non-cgo", func(t *testing.T) {
+		testBuildmodePIE(t, false, true)
+	})
+	if canCgo {
+		switch runtime.GOOS {
+		case "darwin", "freebsd", "linux", "windows":
+			t.Run("cgo", func(t *testing.T) {
+				testBuildmodePIE(t, true, true)
+			})
+		}
+	}
+}
 
+func TestWindowsDefaultBuildmodIsPIE(t *testing.T) {
+	if testing.Short() && testenv.Builder() == "" {
+		t.Skipf("skipping in -short mode on non-builder")
+	}
+
+	if runtime.GOOS != "windows" {
+		t.Skip("skipping windows only test")
+	}
+
+	t.Run("non-cgo", func(t *testing.T) {
+		testBuildmodePIE(t, false, false)
+	})
+	if canCgo {
+		t.Run("cgo", func(t *testing.T) {
+			testBuildmodePIE(t, true, false)
+		})
+	}
+}
+
+func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) {
 	tg := testgo(t)
 	defer tg.cleanup()
 	tg.parallel()
 
-	tg.tempFile("main.go", `package main; func main() { print("hello") }`)
+	var s string
+	if useCgo {
+		s = `import "C";`
+	}
+	tg.tempFile("main.go", fmt.Sprintf(`package main;%s func main() { print("hello") }`, s))
 	src := tg.path("main.go")
-	obj := tg.path("main")
-	tg.run("build", "-buildmode=pie", "-o", obj, src)
+	obj := tg.path("main.exe")
+	args := []string{"build"}
+	if setBuildmodeToPIE {
+		args = append(args, "-buildmode=pie")
+	}
+	args = append(args, "-o", obj, src)
+	tg.run(args...)
 
 	switch runtime.GOOS {
 	case "linux", "android", "freebsd":
@@ -4020,6 +2139,33 @@
 		if f.Flags&macho.FlagPIE == 0 {
 			t.Error("PIE must have PIE flag, but not")
 		}
+	case "windows":
+		f, err := pe.Open(obj)
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer f.Close()
+		if f.Section(".reloc") == nil {
+			t.Error(".reloc section is not present")
+		}
+		if (f.FileHeader.Characteristics & pe.IMAGE_FILE_RELOCS_STRIPPED) != 0 {
+			t.Error("IMAGE_FILE_RELOCS_STRIPPED flag is set")
+		}
+		var dc uint16
+		switch oh := f.OptionalHeader.(type) {
+		case *pe.OptionalHeader32:
+			dc = oh.DllCharacteristics
+		case *pe.OptionalHeader64:
+			dc = oh.DllCharacteristics
+			if (dc & pe.IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA) == 0 {
+				t.Error("IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA flag is not set")
+			}
+		default:
+			t.Fatalf("unexpected optional header type of %T", f.OptionalHeader)
+		}
+		if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
+			t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
+		}
 	default:
 		panic("unreachable")
 	}
@@ -4034,93 +2180,6 @@
 	}
 }
 
-func TestExecBuildX(t *testing.T) {
-	tooSlow(t)
-	if !canCgo {
-		t.Skip("skipping because cgo not enabled")
-	}
-
-	testenv.MustHaveExecPath(t, "/usr/bin/env")
-	testenv.MustHaveExecPath(t, "bash")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	tg.tempDir("cache")
-	tg.setenv("GOCACHE", tg.path("cache"))
-
-	// Before building our test main.go, ensure that an up-to-date copy of
-	// runtime/cgo is present in the cache. If it isn't, the 'go build' step below
-	// will fail with "can't open import". See golang.org/issue/29004.
-	tg.run("build", "runtime/cgo")
-
-	tg.tempFile("main.go", `package main; import "C"; func main() { print("hello") }`)
-	src := tg.path("main.go")
-	obj := tg.path("main")
-	tg.run("build", "-x", "-o", obj, src)
-	sh := tg.path("test.sh")
-	cmds := tg.getStderr()
-	err := ioutil.WriteFile(sh, []byte("set -e\n"+cmds), 0666)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	out, err := exec.Command(obj).CombinedOutput()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if string(out) != "hello" {
-		t.Fatalf("got %q; want %q", out, "hello")
-	}
-
-	err = os.Remove(obj)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	out, err = exec.Command("/usr/bin/env", "bash", "-x", sh).CombinedOutput()
-	if err != nil {
-		t.Fatalf("/bin/sh %s: %v\n%s", sh, err, out)
-	}
-	t.Logf("shell output:\n%s", out)
-
-	out, err = exec.Command(obj).CombinedOutput()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if string(out) != "hello" {
-		t.Fatalf("got %q; want %q", out, "hello")
-	}
-
-	matches := regexp.MustCompile(`^WORK=(.*)\n`).FindStringSubmatch(cmds)
-	if len(matches) == 0 {
-		t.Fatal("no WORK directory")
-	}
-	tg.must(robustio.RemoveAll(matches[1]))
-}
-
-func TestParallelNumber(t *testing.T) {
-	tooSlow(t)
-	for _, n := range [...]string{"-1", "0"} {
-		t.Run(n, func(t *testing.T) {
-			tg := testgo(t)
-			defer tg.cleanup()
-			tg.runFail("test", "-parallel", n, "testdata/standalone_parallel_sub_test.go")
-			tg.grepBoth("-parallel can only be given", "go test -parallel with N<1 did not error")
-		})
-	}
-}
-
-func TestWrongGOOSErrorBeforeLoadError(t *testing.T) {
-	skipIfGccgo(t, "gccgo assumes cross-compilation is always possible")
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.setenv("GOOS", "windwos")
-	tg.runFail("build", "exclude")
-	tg.grepStderr("unsupported GOOS/GOARCH pair", "GOOS=windwos go build exclude did not report 'unsupported GOOS/GOARCH pair'")
-}
-
 func TestUpxCompression(t *testing.T) {
 	if runtime.GOOS != "linux" ||
 		(runtime.GOARCH != "amd64" && runtime.GOARCH != "386") {
@@ -4304,30 +2363,6 @@
 	tg.setenv("GOPATH", tg.tempdir)
 	tg.setenv("GOCACHE", tg.path("cache"))
 
-	if runtime.Compiler != "gccgo" {
-		// timeout here should not affect result being cached
-		// or being retrieved later.
-		tg.run("test", "-x", "-timeout=10s", "errors")
-		tg.grepStderr(`[\\/]compile|gccgo`, "did not run compiler")
-		tg.grepStderr(`[\\/]link|gccgo`, "did not run linker")
-		tg.grepStderr(`errors\.test`, "did not run test")
-
-		tg.run("test", "-x", "errors")
-		tg.grepStdout(`ok  \terrors\t\(cached\)`, "did not report cached result")
-		tg.grepStderrNot(`[\\/]compile|gccgo`, "incorrectly ran compiler")
-		tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly ran linker")
-		tg.grepStderrNot(`errors\.test`, "incorrectly ran test")
-		tg.grepStderrNot("DO NOT USE", "poisoned action status leaked")
-
-		// Even very low timeouts do not disqualify cached entries.
-		tg.run("test", "-timeout=1ns", "-x", "errors")
-		tg.grepStderrNot(`errors\.test`, "incorrectly ran test")
-
-		tg.run("clean", "-testcache")
-		tg.run("test", "-x", "errors")
-		tg.grepStderr(`errors\.test`, "did not run test")
-	}
-
 	// The -p=1 in the commands below just makes the -x output easier to read.
 
 	t.Log("\n\nINITIAL\n\n")
@@ -4407,53 +2442,6 @@
 	}
 }
 
-func TestTestVet(t *testing.T) {
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-
-	tg.tempFile("p1_test.go", `
-		package p
-		import "testing"
-		func Test(t *testing.T) {
-			t.Logf("%d") // oops
-		}
-	`)
-
-	tg.runFail("test", tg.path("p1_test.go"))
-	tg.grepStderr(`Logf format %d`, "did not diagnose bad Logf")
-	tg.run("test", "-vet=off", tg.path("p1_test.go"))
-	tg.grepStdout(`^ok`, "did not print test summary")
-
-	tg.tempFile("p1.go", `
-		package p
-		import "fmt"
-		func F() {
-			fmt.Printf("%d") // oops
-		}
-	`)
-	tg.runFail("test", tg.path("p1.go"))
-	tg.grepStderr(`Printf format %d`, "did not diagnose bad Printf")
-	tg.run("test", "-x", "-vet=shift", tg.path("p1.go"))
-	tg.grepStderr(`[\\/]vet.*-shift`, "did not run vet with -shift")
-	tg.grepStdout(`\[no test files\]`, "did not print test summary")
-	tg.run("test", "-vet=off", tg.path("p1.go"))
-	tg.grepStdout(`\[no test files\]`, "did not print test summary")
-
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.run("test", "vetcycle") // must not fail; #22890
-
-	tg.runFail("test", "vetfail/...")
-	tg.grepStderr(`Printf format %d`, "did not diagnose bad Printf")
-	tg.grepStdout(`ok\s+vetfail/p2`, "did not run vetfail/p2")
-
-	// Use -a so that we need to recompute the vet-specific export data for
-	// vetfail/p1.
-	tg.run("test", "-a", "vetfail/p2")
-	tg.grepStderrNot(`invalid.*constraint`, "did diagnose bad build constraint in vetxonly mode")
-}
-
 func TestTestSkipVetAfterFailedBuild(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -4549,92 +2537,6 @@
 	tg.mustExist(p1)
 }
 
-func TestGoTestJSON(t *testing.T) {
-	skipIfGccgo(t, "gccgo does not have standard packages")
-	tooSlow(t)
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-	tg.setenv("GOCACHE", tg.tempdir)
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-
-	// It would be nice to test that the output is interlaced
-	// but it seems to be impossible to do that in a short test
-	// that isn't also flaky. Just check that we get JSON output.
-	tg.run("test", "-json", "-short", "-v", "errors", "empty/pkg", "skipper")
-	tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
-	tg.grepStdout(`"Action":"run"`, "did not see JSON output")
-
-	tg.grepStdout(`"Action":"output","Package":"empty/pkg","Output":".*no test files`, "did not see no test files print")
-	tg.grepStdout(`"Action":"skip","Package":"empty/pkg"`, "did not see skip")
-
-	tg.grepStdout(`"Action":"output","Package":"skipper","Test":"Test","Output":"--- SKIP:`, "did not see SKIP output")
-	tg.grepStdout(`"Action":"skip","Package":"skipper","Test":"Test"`, "did not see skip result for Test")
-
-	tg.run("test", "-json", "-short", "-v", "errors")
-	tg.grepStdout(`"Action":"output","Package":"errors","Output":".*\(cached\)`, "did not see no cached output")
-
-	tg.run("test", "-json", "-bench=NONE", "-short", "-v", "errors")
-	tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
-	tg.grepStdout(`"Action":"run"`, "did not see JSON output")
-
-	tg.run("test", "-o", tg.path("errors.test.exe"), "-c", "errors")
-	tg.run("tool", "test2json", "-p", "errors", tg.path("errors.test.exe"), "-test.v", "-test.short")
-	tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
-	tg.grepStdout(`"Action":"run"`, "did not see JSON output")
-	tg.grepStdout(`\{"Action":"pass","Package":"errors"\}`, "did not see final pass")
-}
-
-func TestFailFast(t *testing.T) {
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	tests := []struct {
-		run      string
-		failfast bool
-		nfail    int
-	}{
-		{"TestFailingA", true, 1},
-		{"TestFailing[AB]", true, 1},
-		{"TestFailing[AB]", false, 2},
-		// mix with non-failing tests:
-		{"TestA|TestFailing[AB]", true, 1},
-		{"TestA|TestFailing[AB]", false, 2},
-		// mix with parallel tests:
-		{"TestFailingB|TestParallelFailingA", true, 2},
-		{"TestFailingB|TestParallelFailingA", false, 2},
-		{"TestFailingB|TestParallelFailing[AB]", true, 3},
-		{"TestFailingB|TestParallelFailing[AB]", false, 3},
-		// mix with parallel sub-tests
-		{"TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA", true, 3},
-		{"TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA", false, 5},
-		{"TestParallelFailingSubtestsA", true, 1},
-		// only parallels:
-		{"TestParallelFailing[AB]", false, 2},
-		// non-parallel subtests:
-		{"TestFailingSubtestsA", true, 1},
-		{"TestFailingSubtestsA", false, 2},
-		// fatal test
-		{"TestFatal[CD]", true, 1},
-		{"TestFatal[CD]", false, 2},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.run, func(t *testing.T) {
-			tg.runFail("test", "./testdata/src/failfast_test.go", "-run="+tt.run, "-failfast="+strconv.FormatBool(tt.failfast))
-
-			nfail := strings.Count(tg.getStdout(), "FAIL - ")
-
-			if nfail != tt.nfail {
-				t.Errorf("go test -run=%s -failfast=%t printed %d FAILs, want %d", tt.run, tt.failfast, nfail, tt.nfail)
-			}
-		})
-	}
-}
-
 // Issue 22986.
 func TestImportPath(t *testing.T) {
 	tooSlow(t)
@@ -4723,7 +2625,7 @@
 	tg.tempFile("src/-x/x.go", "package x\n")
 	tg.setenv("GOPATH", tg.path("."))
 	tg.runFail("build", "--", "-x")
-	tg.grepStderr("invalid input directory name \"-x\"", "did not reject -x directory")
+	tg.grepStderr("invalid import path \"-x\"", "did not reject -x import path")
 
 	tg.tempFile("src/-x/y/y.go", "package y\n")
 	tg.setenv("GOPATH", tg.path("."))
@@ -4731,118 +2633,6 @@
 	tg.grepStderr("invalid import path \"-x/y\"", "did not reject -x/y import path")
 }
 
-func TestBadCgoDirectives(t *testing.T) {
-	if !canCgo {
-		t.Skip("no cgo")
-	}
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	tg.tempFile("src/x/x.go", "package x\n")
-	tg.setenv("GOPATH", tg.path("."))
-
-	if runtime.Compiler == "gc" {
-		tg.tempFile("src/x/x.go", `package x
-
-			//go:cgo_ldflag "-fplugin=foo.so"
-
-			import "C"
-		`)
-		tg.runFail("build", "x")
-		tg.grepStderr("//go:cgo_ldflag .* only allowed in cgo-generated code", "did not reject //go:cgo_ldflag directive")
-	}
-
-	tg.must(os.Remove(tg.path("src/x/x.go")))
-	tg.runFail("build", "x")
-	tg.grepStderr("no Go files", "did not report missing source code")
-	tg.tempFile("src/x/_cgo_yy.go", `package x
-
-		//go:cgo_ldflag "-fplugin=foo.so"
-
-		import "C"
-	`)
-	tg.runFail("build", "x")
-	tg.grepStderr("no Go files", "did not report missing source code") // _* files are ignored...
-
-	if runtime.Compiler == "gc" {
-		tg.runFail("build", tg.path("src/x/_cgo_yy.go")) // ... but if forced, the comment is rejected
-		// Actually, today there is a separate issue that _ files named
-		// on the command line are ignored. Once that is fixed,
-		// we want to see the cgo_ldflag error.
-		tg.grepStderr("//go:cgo_ldflag only allowed in cgo-generated code|no Go files", "did not reject //go:cgo_ldflag directive")
-	}
-
-	tg.must(os.Remove(tg.path("src/x/_cgo_yy.go")))
-
-	tg.tempFile("src/x/x.go", "package x\n")
-	tg.tempFile("src/x/y.go", `package x
-		// #cgo CFLAGS: -fplugin=foo.so
-		import "C"
-	`)
-	tg.runFail("build", "x")
-	tg.grepStderr("invalid flag in #cgo CFLAGS: -fplugin=foo.so", "did not reject -fplugin")
-
-	tg.tempFile("src/x/y.go", `package x
-		// #cgo CFLAGS: -Ibar -fplugin=foo.so
-		import "C"
-	`)
-	tg.runFail("build", "x")
-	tg.grepStderr("invalid flag in #cgo CFLAGS: -fplugin=foo.so", "did not reject -fplugin")
-
-	tg.tempFile("src/x/y.go", `package x
-		// #cgo pkg-config: -foo
-		import "C"
-	`)
-	tg.runFail("build", "x")
-	tg.grepStderr("invalid pkg-config package name: -foo", "did not reject pkg-config: -foo")
-
-	tg.tempFile("src/x/y.go", `package x
-		// #cgo pkg-config: @foo
-		import "C"
-	`)
-	tg.runFail("build", "x")
-	tg.grepStderr("invalid pkg-config package name: @foo", "did not reject pkg-config: -foo")
-
-	tg.tempFile("src/x/y.go", `package x
-		// #cgo CFLAGS: @foo
-		import "C"
-	`)
-	tg.runFail("build", "x")
-	tg.grepStderr("invalid flag in #cgo CFLAGS: @foo", "did not reject @foo flag")
-
-	tg.tempFile("src/x/y.go", `package x
-		// #cgo CFLAGS: -D
-		import "C"
-	`)
-	tg.runFail("build", "x")
-	tg.grepStderr("invalid flag in #cgo CFLAGS: -D without argument", "did not reject trailing -I flag")
-
-	// Note that -I @foo is allowed because we rewrite it into -I /path/to/src/@foo
-	// before the check is applied. There's no such rewrite for -D.
-
-	tg.tempFile("src/x/y.go", `package x
-		// #cgo CFLAGS: -D @foo
-		import "C"
-	`)
-	tg.runFail("build", "x")
-	tg.grepStderr("invalid flag in #cgo CFLAGS: -D @foo", "did not reject -D @foo flag")
-
-	tg.tempFile("src/x/y.go", `package x
-		// #cgo CFLAGS: -D@foo
-		import "C"
-	`)
-	tg.runFail("build", "x")
-	tg.grepStderr("invalid flag in #cgo CFLAGS: -D@foo", "did not reject -D@foo flag")
-
-	tg.setenv("CGO_CFLAGS", "-D@foo")
-	tg.tempFile("src/x/y.go", `package x
-		import "C"
-	`)
-	tg.run("build", "-n", "x")
-	tg.grepStderr("-D@foo", "did not find -D@foo in commands")
-}
-
 func TestTwoPkgConfigs(t *testing.T) {
 	if !canCgo {
 		t.Skip("no cgo")
@@ -4978,52 +2768,6 @@
 	}
 }
 
-func testCDAndGOPATHAreDifferent(tg *testgoData, cd, gopath string) {
-	skipIfGccgo(tg.t, "gccgo does not support -ldflags -X")
-	tg.setenv("GOPATH", gopath)
-
-	tg.tempDir("dir")
-	exe := tg.path("dir/a.exe")
-
-	tg.cd(cd)
-
-	tg.run("build", "-o", exe, "-ldflags", "-X=my.pkg.Text=linkXworked")
-	out, err := exec.Command(exe).CombinedOutput()
-	if err != nil {
-		tg.t.Fatal(err)
-	}
-	if string(out) != "linkXworked\n" {
-		tg.t.Errorf(`incorrect output with GOPATH=%q and CD=%q: expected "linkXworked\n", but have %q`, gopath, cd, string(out))
-	}
-}
-
-func TestCDAndGOPATHAreDifferent(t *testing.T) {
-	tg := testgo(t)
-	defer tg.cleanup()
-
-	gopath := filepath.Join(tg.pwd(), "testdata")
-	cd := filepath.Join(gopath, "src/my.pkg/main")
-
-	testCDAndGOPATHAreDifferent(tg, cd, gopath)
-	if runtime.GOOS == "windows" {
-		testCDAndGOPATHAreDifferent(tg, cd, strings.ReplaceAll(gopath, `\`, `/`))
-		testCDAndGOPATHAreDifferent(tg, cd, strings.ToUpper(gopath))
-		testCDAndGOPATHAreDifferent(tg, cd, strings.ToLower(gopath))
-	}
-}
-
-// Issue 25579.
-func TestGoBuildDashODevNull(t *testing.T) {
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
-	tg.run("build", "-o", os.DevNull, filepath.Join(tg.pwd(), "testdata", "src", "hello", "hello.go"))
-	tg.mustNotExist("hello")
-	tg.mustNotExist("hello.exe")
-}
-
 // Issue 25093.
 func TestCoverpkgTestOnly(t *testing.T) {
 	skipIfGccgo(t, "gccgo has no cover tool")
diff --git a/libgo/go/cmd/go/help_test.go b/libgo/go/cmd/go/help_test.go
index 9bcab82..78d63ff 100644
--- a/libgo/go/cmd/go/help_test.go
+++ b/libgo/go/cmd/go/help_test.go
@@ -14,6 +14,8 @@
 )
 
 func TestDocsUpToDate(t *testing.T) {
+	t.Parallel()
+
 	if !modload.Enabled() {
 		t.Skipf("help.Help in GOPATH mode is configured by main.main")
 	}
diff --git a/libgo/go/cmd/go/internal/auth/auth.go b/libgo/go/cmd/go/internal/auth/auth.go
index 12e3c74..fe5a89d 100644
--- a/libgo/go/cmd/go/internal/auth/auth.go
+++ b/libgo/go/cmd/go/internal/auth/auth.go
@@ -10,10 +10,12 @@
 // AddCredentials fills in the user's credentials for req, if any.
 // The return value reports whether any matching credentials were found.
 func AddCredentials(req *http.Request) (added bool) {
+	host := req.URL.Hostname()
+
 	// TODO(golang.org/issue/26232): Support arbitrary user-provided credentials.
 	netrcOnce.Do(readNetrc)
 	for _, l := range netrc {
-		if l.machine == req.URL.Host {
+		if l.machine == host {
 			req.SetBasicAuth(l.login, l.password)
 			return true
 		}
diff --git a/libgo/go/cmd/go/internal/base/base.go b/libgo/go/cmd/go/internal/base/base.go
index 272da55..ab2f1bb 100644
--- a/libgo/go/cmd/go/internal/base/base.go
+++ b/libgo/go/cmd/go/internal/base/base.go
@@ -7,11 +7,8 @@
 package base
 
 import (
-	"bytes"
-	"errors"
 	"flag"
 	"fmt"
-	"go/scanner"
 	"log"
 	"os"
 	"os/exec"
@@ -172,25 +169,3 @@
 // Usage is the usage-reporting function, filled in by package main
 // but here for reference by other packages.
 var Usage func()
-
-// ExpandScanner expands a scanner.List error into all the errors in the list.
-// The default Error method only shows the first error
-// and does not shorten paths.
-func ExpandScanner(err error) error {
-	// Look for parser errors.
-	if err, ok := err.(scanner.ErrorList); ok {
-		// Prepare error with \n before each message.
-		// When printed in something like context: %v
-		// this will put the leading file positions each on
-		// its own line. It will also show all the errors
-		// instead of just the first, as err.Error does.
-		var buf bytes.Buffer
-		for _, e := range err {
-			e.Pos.Filename = ShortPath(e.Pos.Filename)
-			buf.WriteString("\n")
-			buf.WriteString(e.Error())
-		}
-		return errors.New(buf.String())
-	}
-	return err
-}
diff --git a/libgo/go/cmd/go/internal/base/env.go b/libgo/go/cmd/go/internal/base/env.go
index 077295e..5f2665d 100644
--- a/libgo/go/cmd/go/internal/base/env.go
+++ b/libgo/go/cmd/go/internal/base/env.go
@@ -4,12 +4,12 @@
 
 package base
 
-// EnvForDir returns a modified environment suitable for running in the given
-// directory.
-// The environment is the supplied base environment but with an updated $PWD, so
-// that an os.Getwd in the child will be faster.
-func EnvForDir(dir string, base []string) []string {
-	// Internally we only use rooted paths, so dir is rooted.
-	// Even if dir is not rooted, no harm done.
+// AppendPWD returns the result of appending PWD=dir to the environment base.
+//
+// The resulting environment makes os.Getwd more efficient for a subprocess
+// running in dir.
+func AppendPWD(base []string, dir string) []string {
+	// Internally we only use absolute paths, so dir is absolute.
+	// Even if dir is not absolute, no harm done.
 	return append(base, "PWD="+dir)
 }
diff --git a/libgo/go/cmd/go/internal/base/goflags.go b/libgo/go/cmd/go/internal/base/goflags.go
index 187c2a1..3476613 100644
--- a/libgo/go/cmd/go/internal/base/goflags.go
+++ b/libgo/go/cmd/go/internal/base/goflags.go
@@ -102,7 +102,7 @@
 }
 
 // SetFromGOFLAGS sets the flags in the given flag set using settings in $GOFLAGS.
-func SetFromGOFLAGS(flags flag.FlagSet) {
+func SetFromGOFLAGS(flags *flag.FlagSet) {
 	InitGOFLAGS()
 
 	// This loop is similar to flag.Parse except that it ignores
@@ -125,14 +125,18 @@
 		if f == nil {
 			continue
 		}
+
+		// Use flags.Set consistently (instead of f.Value.Set) so that a subsequent
+		// call to flags.Visit will correctly visit the flags that have been set.
+
 		if fb, ok := f.Value.(boolFlag); ok && fb.IsBoolFlag() {
 			if hasValue {
-				if err := fb.Set(value); err != nil {
+				if err := flags.Set(f.Name, value); err != nil {
 					fmt.Fprintf(flags.Output(), "go: invalid boolean value %q for flag %s (from %s): %v\n", value, name, where, err)
 					flags.Usage()
 				}
 			} else {
-				if err := fb.Set("true"); err != nil {
+				if err := flags.Set(f.Name, "true"); err != nil {
 					fmt.Fprintf(flags.Output(), "go: invalid boolean flag %s (from %s): %v\n", name, where, err)
 					flags.Usage()
 				}
@@ -142,7 +146,7 @@
 				fmt.Fprintf(flags.Output(), "go: flag needs an argument: %s (from %s)\n", name, where)
 				flags.Usage()
 			}
-			if err := f.Value.Set(value); err != nil {
+			if err := flags.Set(f.Name, value); err != nil {
 				fmt.Fprintf(flags.Output(), "go: invalid value %q for flag %s (from %s): %v\n", value, name, where, err)
 				flags.Usage()
 			}
diff --git a/libgo/go/cmd/go/internal/cache/cache.go b/libgo/go/cmd/go/internal/cache/cache.go
index 8797398..15545ac 100644
--- a/libgo/go/cmd/go/internal/cache/cache.go
+++ b/libgo/go/cmd/go/internal/cache/cache.go
@@ -108,7 +108,7 @@
 // GODEBUG=gocacheverify=1.
 var verify = false
 
-var errVerifyMode = errors.New("gocachverify=1")
+var errVerifyMode = errors.New("gocacheverify=1")
 
 // DebugTest is set when GODEBUG=gocachetest=1 is in the environment.
 var DebugTest = false
diff --git a/libgo/go/cmd/go/internal/cfg/cfg.go b/libgo/go/cmd/go/internal/cfg/cfg.go
index 61dc6bd..7f8f8e9 100644
--- a/libgo/go/cmd/go/internal/cfg/cfg.go
+++ b/libgo/go/cmd/go/internal/cfg/cfg.go
@@ -236,6 +236,7 @@
 	GOROOTpkg    = filepath.Join(GOROOT, "pkg")
 	GOROOTsrc    = filepath.Join(GOROOT, "src")
 	GOROOT_FINAL = findGOROOT_FINAL()
+	GOMODCACHE   = envOr("GOMODCACHE", gopathDir("pkg/mod"))
 
 	// Used in envcmd.MkEnv and build ID computations.
 	GOARM    = envOr("GOARM", fmt.Sprint(objabi.GOARM))
@@ -253,6 +254,8 @@
 	GOINSECURE = Getenv("GOINSECURE")
 )
 
+var SumdbDir = gopathDir("pkg/sumdb")
+
 // GetArchEnv returns the name and setting of the
 // GOARCH-specific architecture environment variable.
 // If the current architecture has no GOARCH-specific variable,
@@ -364,3 +367,11 @@
 	}
 	return stat.IsDir()
 }
+
+func gopathDir(rel string) string {
+	list := filepath.SplitList(BuildContext.GOPATH)
+	if len(list) == 0 || list[0] == "" {
+		return ""
+	}
+	return filepath.Join(list[0], rel)
+}
diff --git a/libgo/go/cmd/go/internal/clean/clean.go b/libgo/go/cmd/go/internal/clean/clean.go
index 69e1748..99704cb 100644
--- a/libgo/go/cmd/go/internal/clean/clean.go
+++ b/libgo/go/cmd/go/internal/clean/clean.go
@@ -137,20 +137,27 @@
 				if cfg.BuildN || cfg.BuildX {
 					b.Showcmd("", "rm -r %s", strings.Join(subdirs, " "))
 				}
-				for _, d := range subdirs {
-					// Only print the first error - there may be many.
-					// This also mimics what os.RemoveAll(dir) would do.
-					if err := os.RemoveAll(d); err != nil && !printedErrors {
-						printedErrors = true
-						base.Errorf("go clean -cache: %v", err)
+				if !cfg.BuildN {
+					for _, d := range subdirs {
+						// Only print the first error - there may be many.
+						// This also mimics what os.RemoveAll(dir) would do.
+						if err := os.RemoveAll(d); err != nil && !printedErrors {
+							printedErrors = true
+							base.Errorf("go clean -cache: %v", err)
+						}
 					}
 				}
 			}
 
 			logFile := filepath.Join(dir, "log.txt")
-			if err := os.RemoveAll(logFile); err != nil && !printedErrors {
-				printedErrors = true
-				base.Errorf("go clean -cache: %v", err)
+			if cfg.BuildN || cfg.BuildX {
+				b.Showcmd("", "rm -f %s", logFile)
+			}
+			if !cfg.BuildN {
+				if err := os.RemoveAll(logFile); err != nil && !printedErrors {
+					printedErrors = true
+					base.Errorf("go clean -cache: %v", err)
+				}
 			}
 		}
 	}
@@ -186,14 +193,14 @@
 	}
 
 	if cleanModcache {
-		if modfetch.PkgMod == "" {
+		if cfg.GOMODCACHE == "" {
 			base.Fatalf("go clean -modcache: no module cache")
 		}
 		if cfg.BuildN || cfg.BuildX {
-			b.Showcmd("", "rm -rf %s", modfetch.PkgMod)
+			b.Showcmd("", "rm -rf %s", cfg.GOMODCACHE)
 		}
 		if !cfg.BuildN {
-			if err := modfetch.RemoveAll(modfetch.PkgMod); err != nil {
+			if err := modfetch.RemoveAll(cfg.GOMODCACHE); err != nil {
 				base.Errorf("go clean -modcache: %v", err)
 			}
 		}
@@ -232,7 +239,7 @@
 	cleaned[p] = true
 
 	if p.Dir == "" {
-		base.Errorf("can't load package: %v", p.Error)
+		base.Errorf("%v", p.Error)
 		return
 	}
 	dirs, err := ioutil.ReadDir(p.Dir)
diff --git a/libgo/go/cmd/go/internal/cmdflag/flag.go b/libgo/go/cmd/go/internal/cmdflag/flag.go
index 3f93432..8abb7e5 100644
--- a/libgo/go/cmd/go/internal/cmdflag/flag.go
+++ b/libgo/go/cmd/go/internal/cmdflag/flag.go
@@ -6,13 +6,10 @@
 package cmdflag
 
 import (
+	"errors"
 	"flag"
 	"fmt"
-	"os"
-	"strconv"
 	"strings"
-
-	"cmd/go/internal/base"
 )
 
 // The flag handling part of go commands such as test is large and distracting.
@@ -20,141 +17,113 @@
 // our command line are for us, and some are for the binary we're running,
 // and some are for both.
 
-// Defn defines a flag we know about.
-type Defn struct {
-	Name       string     // Name on command line.
-	BoolVar    *bool      // If it's a boolean flag, this points to it.
-	Value      flag.Value // The flag.Value represented.
-	PassToTest bool       // Pass to the test binary? Used only by go test.
-	Present    bool       // Flag has been seen.
+// ErrFlagTerminator indicates the distinguished token "--", which causes the
+// flag package to treat all subsequent arguments as non-flags.
+var ErrFlagTerminator = errors.New("flag terminator")
+
+// A FlagNotDefinedError indicates a flag-like argument that does not correspond
+// to any registered flag in a FlagSet.
+type FlagNotDefinedError struct {
+	RawArg   string // the original argument, like --foo or -foo=value
+	Name     string
+	HasValue bool   // is this the -foo=value or --foo=value form?
+	Value    string // only provided if HasValue is true
 }
 
-// IsBool reports whether v is a bool flag.
-func IsBool(v flag.Value) bool {
-	vv, ok := v.(interface {
-		IsBoolFlag() bool
-	})
-	if ok {
-		return vv.IsBoolFlag()
-	}
-	return false
+func (e FlagNotDefinedError) Error() string {
+	return fmt.Sprintf("flag provided but not defined: -%s", e.Name)
 }
 
-// SetBool sets the addressed boolean to the value.
-func SetBool(cmd string, flag *bool, value string) {
-	x, err := strconv.ParseBool(value)
-	if err != nil {
-		SyntaxError(cmd, "illegal bool flag value "+value)
-	}
-	*flag = x
+// A NonFlagError indicates an argument that is not a syntactically-valid flag.
+type NonFlagError struct {
+	RawArg string
 }
 
-// SetInt sets the addressed integer to the value.
-func SetInt(cmd string, flag *int, value string) {
-	x, err := strconv.Atoi(value)
-	if err != nil {
-		SyntaxError(cmd, "illegal int flag value "+value)
-	}
-	*flag = x
+func (e NonFlagError) Error() string {
+	return fmt.Sprintf("not a flag: %q", e.RawArg)
 }
 
-// SyntaxError reports an argument syntax error and exits the program.
-func SyntaxError(cmd, msg string) {
-	fmt.Fprintf(os.Stderr, "go %s: %s\n", cmd, msg)
-	if cmd == "test" {
-		fmt.Fprintf(os.Stderr, `run "go help %s" or "go help testflag" for more information`+"\n", cmd)
-	} else {
-		fmt.Fprintf(os.Stderr, `run "go help %s" for more information`+"\n", cmd)
-	}
-	base.SetExitStatus(2)
-	base.Exit()
-}
+// ParseOne sees if args[0] is present in the given flag set and if so,
+// sets its value and returns the flag along with the remaining (unused) arguments.
+//
+// ParseOne always returns either a non-nil Flag or a non-nil error,
+// and always consumes at least one argument (even on error).
+//
+// Unlike (*flag.FlagSet).Parse, ParseOne does not log its own errors.
+func ParseOne(fs *flag.FlagSet, args []string) (f *flag.Flag, remainingArgs []string, err error) {
+	// This function is loosely derived from (*flag.FlagSet).parseOne.
 
-// AddKnownFlags registers the flags in defns with base.AddKnownFlag.
-func AddKnownFlags(cmd string, defns []*Defn) {
-	for _, f := range defns {
-		base.AddKnownFlag(f.Name)
-		base.AddKnownFlag(cmd + "." + f.Name)
+	raw, args := args[0], args[1:]
+	arg := raw
+	if strings.HasPrefix(arg, "--") {
+		if arg == "--" {
+			return nil, args, ErrFlagTerminator
+		}
+		arg = arg[1:] // reduce two minuses to one
 	}
-}
 
-// Parse sees if argument i is present in the definitions and if so,
-// returns its definition, value, and whether it consumed an extra word.
-// If the flag begins (cmd.Name()+".") it is ignored for the purpose of this function.
-func Parse(cmd string, usage func(), defns []*Defn, args []string, i int) (f *Defn, value string, extra bool) {
-	arg := args[i]
-	if strings.HasPrefix(arg, "--") { // reduce two minuses to one
-		arg = arg[1:]
-	}
 	switch arg {
 	case "-?", "-h", "-help":
-		usage()
+		return nil, args, flag.ErrHelp
 	}
-	if arg == "" || arg[0] != '-' {
-		return
+	if len(arg) < 2 || arg[0] != '-' || arg[1] == '-' || arg[1] == '=' {
+		return nil, args, NonFlagError{RawArg: raw}
 	}
+
 	name := arg[1:]
-	// If there's already a prefix such as "test.", drop it for now.
-	name = strings.TrimPrefix(name, cmd+".")
-	equals := strings.Index(name, "=")
-	if equals >= 0 {
-		value = name[equals+1:]
-		name = name[:equals]
+	hasValue := false
+	value := ""
+	if i := strings.Index(name, "="); i >= 0 {
+		value = name[i+1:]
+		hasValue = true
+		name = name[0:i]
 	}
-	for _, f = range defns {
-		if name == f.Name {
-			// Booleans are special because they have modes -x, -x=true, -x=false.
-			if f.BoolVar != nil || IsBool(f.Value) {
-				if equals < 0 { // Otherwise, it's been set and will be verified in SetBool.
-					value = "true"
-				} else {
-					// verify it parses
-					SetBool(cmd, new(bool), value)
-				}
-			} else { // Non-booleans must have a value.
-				extra = equals < 0
-				if extra {
-					if i+1 >= len(args) {
-						SyntaxError(cmd, "missing argument for flag "+f.Name)
-					}
-					value = args[i+1]
-				}
-			}
-			if f.Present {
-				SyntaxError(cmd, f.Name+" flag may be set only once")
-			}
-			f.Present = true
-			return
+
+	f = fs.Lookup(name)
+	if f == nil {
+		return nil, args, FlagNotDefinedError{
+			RawArg:   raw,
+			Name:     name,
+			HasValue: hasValue,
+			Value:    value,
 		}
 	}
-	f = nil
-	return
+
+	// Use fs.Set instead of f.Value.Set below so that any subsequent call to
+	// fs.Visit will correctly visit the flags that have been set.
+
+	failf := func(format string, a ...interface{}) (*flag.Flag, []string, error) {
+		return f, args, fmt.Errorf(format, a...)
+	}
+
+	if fv, ok := f.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
+		if hasValue {
+			if err := fs.Set(name, value); err != nil {
+				return failf("invalid boolean value %q for -%s: %v", value, name, err)
+			}
+		} else {
+			if err := fs.Set(name, "true"); err != nil {
+				return failf("invalid boolean flag %s: %v", name, err)
+			}
+		}
+	} else {
+		// It must have a value, which might be the next argument.
+		if !hasValue && len(args) > 0 {
+			// value is the next arg
+			hasValue = true
+			value, args = args[0], args[1:]
+		}
+		if !hasValue {
+			return failf("flag needs an argument: -%s", name)
+		}
+		if err := fs.Set(name, value); err != nil {
+			return failf("invalid value %q for flag -%s: %v", value, name, err)
+		}
+	}
+
+	return f, args, nil
 }
 
-// FindGOFLAGS extracts and returns the flags matching defns from GOFLAGS.
-// Ideally the caller would mention that the flags were from GOFLAGS
-// when reporting errors, but that's too hard for now.
-func FindGOFLAGS(defns []*Defn) []string {
-	var flags []string
-	for _, flag := range base.GOFLAGS() {
-		// Flags returned by base.GOFLAGS are well-formed, one of:
-		//	-x
-		//	--x
-		//	-x=value
-		//	--x=value
-		if strings.HasPrefix(flag, "--") {
-			flag = flag[1:]
-		}
-		name := flag[1:]
-		if i := strings.Index(name, "="); i >= 0 {
-			name = name[:i]
-		}
-		for _, f := range defns {
-			if name == f.Name {
-				flags = append(flags, flag)
-				break
-			}
-		}
-	}
-	return flags
+type boolFlag interface {
+	IsBoolFlag() bool
 }
diff --git a/libgo/go/cmd/go/internal/envcmd/env.go b/libgo/go/cmd/go/internal/envcmd/env.go
index d2d5ed9..252025d 100644
--- a/libgo/go/cmd/go/internal/envcmd/env.go
+++ b/libgo/go/cmd/go/internal/envcmd/env.go
@@ -77,6 +77,7 @@
 		{Name: "GOHOSTARCH", Value: runtime.GOARCH},
 		{Name: "GOHOSTOS", Value: runtime.GOOS},
 		{Name: "GOINSECURE", Value: cfg.GOINSECURE},
+		{Name: "GOMODCACHE", Value: cfg.GOMODCACHE},
 		{Name: "GONOPROXY", Value: cfg.GONOPROXY},
 		{Name: "GONOSUMDB", Value: cfg.GONOSUMDB},
 		{Name: "GOOS", Value: cfg.Goos},
diff --git a/libgo/go/cmd/go/internal/fmtcmd/fmt.go b/libgo/go/cmd/go/internal/fmtcmd/fmt.go
index 408af52..d6894ed 100644
--- a/libgo/go/cmd/go/internal/fmtcmd/fmt.go
+++ b/libgo/go/cmd/go/internal/fmtcmd/fmt.go
@@ -6,11 +6,11 @@
 package fmtcmd
 
 import (
+	"errors"
 	"fmt"
 	"os"
 	"path/filepath"
 	"runtime"
-	"strings"
 	"sync"
 
 	"cmd/go/internal/base"
@@ -72,11 +72,12 @@
 			continue
 		}
 		if pkg.Error != nil {
-			if strings.HasPrefix(pkg.Error.Err.Error(), "build constraints exclude all Go files") {
+			var nogo *load.NoGoError
+			if errors.As(pkg.Error, &nogo) && len(pkg.InternalAllGoFiles()) > 0 {
 				// Skip this error, as we will format
 				// all files regardless.
 			} else {
-				base.Errorf("can't load package: %s", pkg.Error)
+				base.Errorf("%v", pkg.Error)
 				continue
 			}
 		}
diff --git a/libgo/go/cmd/go/internal/generate/generate.go b/libgo/go/cmd/go/internal/generate/generate.go
index 315db69..093b198 100644
--- a/libgo/go/cmd/go/internal/generate/generate.go
+++ b/libgo/go/cmd/go/internal/generate/generate.go
@@ -9,7 +9,10 @@
 	"bufio"
 	"bytes"
 	"fmt"
+	"go/parser"
+	"go/token"
 	"io"
+	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -119,6 +122,9 @@
 tag "generate" so that files may be examined by go generate but ignored
 during build.
 
+For packages with invalid code, generate processes only source files with a
+valid package clause.
+
 If any generator returns an error exit status, "go generate" skips
 all further processing for that package.
 
@@ -169,7 +175,7 @@
 
 	// Even if the arguments are .go files, this loop suffices.
 	printed := false
-	for _, pkg := range load.Packages(args) {
+	for _, pkg := range load.PackagesAndErrors(args) {
 		if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main {
 			if !printed {
 				fmt.Fprintf(os.Stderr, "go: not generating in packages in dependency modules\n")
@@ -178,18 +184,14 @@
 			continue
 		}
 
-		pkgName := pkg.Name
-
 		for _, file := range pkg.InternalGoFiles() {
-			if !generate(pkgName, file) {
+			if !generate(file) {
 				break
 			}
 		}
 
-		pkgName += "_test"
-
 		for _, file := range pkg.InternalXGoFiles() {
-			if !generate(pkgName, file) {
+			if !generate(file) {
 				break
 			}
 		}
@@ -197,16 +199,23 @@
 }
 
 // generate runs the generation directives for a single file.
-func generate(pkg, absFile string) bool {
-	fd, err := os.Open(absFile)
+func generate(absFile string) bool {
+	src, err := ioutil.ReadFile(absFile)
 	if err != nil {
 		log.Fatalf("generate: %s", err)
 	}
-	defer fd.Close()
+
+	// Parse package clause
+	filePkg, err := parser.ParseFile(token.NewFileSet(), "", src, parser.PackageClauseOnly)
+	if err != nil {
+		// Invalid package clause - ignore file.
+		return true
+	}
+
 	g := &Generator{
-		r:        fd,
+		r:        bytes.NewReader(src),
 		path:     absFile,
-		pkg:      pkg,
+		pkg:      filePkg.Name.String(),
 		commands: make(map[string][]string),
 	}
 	return g.run()
diff --git a/libgo/go/cmd/go/internal/get/get.go b/libgo/go/cmd/go/internal/get/get.go
index 500e3e0..d38350c 100644
--- a/libgo/go/cmd/go/internal/get/get.go
+++ b/libgo/go/cmd/go/internal/get/get.go
@@ -7,7 +7,6 @@
 
 import (
 	"fmt"
-	"go/build"
 	"os"
 	"path/filepath"
 	"runtime"
@@ -194,12 +193,28 @@
 	for _, arg := range patterns {
 		if strings.Contains(arg, "@") {
 			base.Fatalf("go: cannot use path@version syntax in GOPATH mode")
+			continue
+		}
+
+		// Guard against 'go get x.go', a common mistake.
+		// Note that package and module paths may end with '.go', so only print an error
+		// if the argument has no slash or refers to an existing file.
+		if strings.HasSuffix(arg, ".go") {
+			if !strings.Contains(arg, "/") {
+				base.Errorf("go get %s: arguments must be package or module paths", arg)
+				continue
+			}
+			if fi, err := os.Stat(arg); err == nil && !fi.IsDir() {
+				base.Errorf("go get: %s exists as a file, but 'go get' requires package arguments", arg)
+			}
 		}
 	}
+	base.ExitIfErrors()
+
 	var pkgs []string
 	for _, m := range search.ImportPathsQuiet(patterns) {
-		if len(m.Pkgs) == 0 && strings.Contains(m.Pattern, "...") {
-			pkgs = append(pkgs, m.Pattern)
+		if len(m.Pkgs) == 0 && strings.Contains(m.Pattern(), "...") {
+			pkgs = append(pkgs, m.Pattern())
 		} else {
 			pkgs = append(pkgs, m.Pkgs...)
 		}
@@ -285,10 +300,16 @@
 		// We delay this until after reloadPackage so that the old entry
 		// for p has been replaced in the package cache.
 		if wildcardOkay && strings.Contains(arg, "...") {
-			if build.IsLocalImport(arg) {
-				args = search.MatchPackagesInFS(arg).Pkgs
+			match := search.NewMatch(arg)
+			if match.IsLocal() {
+				match.MatchDirs()
+				args = match.Dirs
 			} else {
-				args = search.MatchPackages(arg).Pkgs
+				match.MatchPackages()
+				args = match.Pkgs
+			}
+			for _, err := range match.Errs {
+				base.Errorf("%s", err)
 			}
 			isWildcard = true
 		}
diff --git a/libgo/go/cmd/go/internal/get/vcs.go b/libgo/go/cmd/go/internal/get/vcs.go
index 2e4d638..fd37fcb 100644
--- a/libgo/go/cmd/go/internal/get/vcs.go
+++ b/libgo/go/cmd/go/internal/get/vcs.go
@@ -430,7 +430,7 @@
 
 	cmd := exec.Command(v.cmd, args...)
 	cmd.Dir = dir
-	cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
+	cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir)
 	if cfg.BuildX {
 		fmt.Fprintf(os.Stderr, "cd %s\n", dir)
 		fmt.Fprintf(os.Stderr, "%s %s\n", v.cmd, strings.Join(args, " "))
diff --git a/libgo/go/cmd/go/internal/help/help.go b/libgo/go/cmd/go/internal/help/help.go
index edb4a2a..7a730fc 100644
--- a/libgo/go/cmd/go/internal/help/help.go
+++ b/libgo/go/cmd/go/internal/help/help.go
@@ -93,7 +93,7 @@
 {{if eq (.UsageLine) "go"}}
 Additional help topics:
 {{range .Commands}}{{if and (not .Runnable) (not .Commands)}}
-	{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
+	{{.Name | printf "%-15s"}} {{.Short}}{{end}}{{end}}
 
 Use "go help{{with .LongName}} {{.}}{{end}} <topic>" for more information about that topic.
 {{end}}
diff --git a/libgo/go/cmd/go/internal/help/helpdoc.go b/libgo/go/cmd/go/internal/help/helpdoc.go
index 6a843f4..e1f0521 100644
--- a/libgo/go/cmd/go/internal/help/helpdoc.go
+++ b/libgo/go/cmd/go/internal/help/helpdoc.go
@@ -493,6 +493,8 @@
 	GOCACHE
 		The directory where the go command will store cached
 		information for reuse in future builds.
+	GOMODCACHE
+		The directory where the go command will store downloaded modules.
 	GODEBUG
 		Enable various debugging facilities. See 'go doc runtime'
 		for details.
@@ -510,6 +512,9 @@
 		Comma-separated list of glob patterns (in the syntax of Go's path.Match)
 		of module path prefixes that should always be fetched in an insecure
 		manner. Only applies to dependencies that are being fetched directly.
+		Unlike the -insecure flag on 'go get', GOINSECURE does not disable
+		checksum database validation. GOPRIVATE or GONOSUMDB may be used
+		to achieve that.
 	GOOS
 		The operating system for which to compile code.
 		Examples are linux, darwin, windows, netbsd.
@@ -762,3 +767,95 @@
 decisions about whether to reuse a cached test result.
 `,
 }
+
+var HelpBuildConstraint = &base.Command{
+	UsageLine: "buildconstraint",
+	Short:     "build constraints",
+	Long: `
+A build constraint, also known as a build tag, is a line comment that begins
+
+	// +build
+
+that lists the conditions under which a file should be included in the package.
+Constraints may appear in any kind of source file (not just Go), but
+they must appear near the top of the file, preceded
+only by blank lines and other line comments. These rules mean that in Go
+files a build constraint must appear before the package clause.
+
+To distinguish build constraints from package documentation, a series of
+build constraints must be followed by a blank line.
+
+A build constraint is evaluated as the OR of space-separated options.
+Each option evaluates as the AND of its comma-separated terms.
+Each term consists of letters, digits, underscores, and dots.
+A term may be negated with a preceding !.
+For example, the build constraint:
+
+	// +build linux,386 darwin,!cgo
+
+corresponds to the boolean formula:
+
+	(linux AND 386) OR (darwin AND (NOT cgo))
+
+A file may have multiple build constraints. The overall constraint is the AND
+of the individual constraints. That is, the build constraints:
+
+	// +build linux darwin
+	// +build amd64
+
+corresponds to the boolean formula:
+
+	(linux OR darwin) AND amd64
+
+During a particular build, the following words are satisfied:
+
+	- the target operating system, as spelled by runtime.GOOS, set with the
+	  GOOS environment variable.
+	- the target architecture, as spelled by runtime.GOARCH, set with the
+	  GOARCH environment variable.
+	- the compiler being used, either "gc" or "gccgo"
+	- "cgo", if the cgo command is supported (see CGO_ENABLED in
+	  'go help environment').
+	- a term for each Go major release, through the current version:
+	  "go1.1" from Go version 1.1 onward, "go1.12" from Go 1.12, and so on.
+	- any additional tags given by the -tags flag (see 'go help build').
+
+There are no separate build tags for beta or minor releases.
+
+If a file's name, after stripping the extension and a possible _test suffix,
+matches any of the following patterns:
+	*_GOOS
+	*_GOARCH
+	*_GOOS_GOARCH
+(example: source_windows_amd64.go) where GOOS and GOARCH represent
+any known operating system and architecture values respectively, then
+the file is considered to have an implicit build constraint requiring
+those terms (in addition to any explicit constraints in the file).
+
+Using GOOS=android matches build tags and files as for GOOS=linux
+in addition to android tags and files.
+
+Using GOOS=illumos matches build tags and files as for GOOS=solaris
+in addition to illumos tags and files.
+
+To keep a file from being considered for the build:
+
+	// +build ignore
+
+(any other unsatisfied word will work as well, but "ignore" is conventional.)
+
+To build a file only when using cgo, and only on Linux and OS X:
+
+	// +build linux,cgo darwin,cgo
+
+Such a file is usually paired with another file implementing the
+default functionality for other systems, which in this case would
+carry the constraint:
+
+	// +build !linux,!darwin !cgo
+
+Naming a file dns_windows.go will cause it to be included only when
+building the package for Windows; similarly, math_386.s will be included
+only when building the package for 32-bit x86.
+`,
+}
diff --git a/libgo/go/cmd/go/internal/list/list.go b/libgo/go/cmd/go/internal/list/list.go
index 8d979e2..6ca1561 100644
--- a/libgo/go/cmd/go/internal/list/list.go
+++ b/libgo/go/cmd/go/internal/list/list.go
@@ -451,6 +451,7 @@
 		pkgs = load.PackagesAndErrors(args)
 	} else {
 		pkgs = load.Packages(args)
+		base.ExitIfErrors()
 	}
 
 	if cache.Default() == nil {
@@ -471,9 +472,6 @@
 		c := cache.Default()
 		// Add test binaries to packages to be listed.
 		for _, p := range pkgs {
-			if p.Error != nil {
-				continue
-			}
 			if len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 {
 				var pmain, ptest, pxtest *load.Package
 				var err error
diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go
index 06b6e23..e146e34 100644
--- a/libgo/go/cmd/go/internal/load/pkg.go
+++ b/libgo/go/cmd/go/internal/load/pkg.go
@@ -187,20 +187,17 @@
 	Gccgoflags []string // -gccgoflags for this package
 }
 
+// A NoGoError indicates that no Go files for the package were applicable to the
+// build for that package.
+//
+// That may be because there were no files whatsoever, or because all files were
+// excluded, or because all non-excluded files were test sources.
 type NoGoError struct {
 	Package *Package
 }
 
 func (e *NoGoError) Error() string {
-	// Count files beginning with _ and ., which we will pretend don't exist at all.
-	dummy := 0
-	for _, name := range e.Package.IgnoredGoFiles {
-		if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") {
-			dummy++
-		}
-	}
-
-	if len(e.Package.IgnoredGoFiles) > dummy {
+	if len(e.Package.constraintIgnoredGoFiles()) > 0 {
 		// Go files exist, but they were ignored due to build constraints.
 		return "build constraints exclude all Go files in " + e.Package.Dir
 	}
@@ -213,6 +210,77 @@
 	return "no Go files in " + e.Package.Dir
 }
 
+// setLoadPackageDataError presents an error found when loading package data
+// as a *PackageError. It has special cases for some common errors to improve
+// messages shown to users and reduce redundancy.
+//
+// setLoadPackageDataError returns true if it's safe to load information about
+// imported packages, for example, if there was a parse error loading imports
+// in one file, but other files are okay.
+func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportStack, importPos []token.Position) {
+	matchErr, isMatchErr := err.(*search.MatchError)
+	if isMatchErr && matchErr.Match.Pattern() == path {
+		if matchErr.Match.IsLiteral() {
+			// The error has a pattern has a pattern similar to the import path.
+			// It may be slightly different (./foo matching example.com/foo),
+			// but close enough to seem redundant.
+			// Unwrap the error so we don't show the pattern.
+			err = matchErr.Err
+		}
+	}
+
+	// Replace (possibly wrapped) *build.NoGoError with *load.NoGoError.
+	// The latter is more specific about the cause.
+	var nogoErr *build.NoGoError
+	if errors.As(err, &nogoErr) {
+		if p.Dir == "" && nogoErr.Dir != "" {
+			p.Dir = nogoErr.Dir
+		}
+		err = &NoGoError{Package: p}
+	}
+
+	// Report the error on the importing package if the problem is with the import declaration
+	// for example, if the package doesn't exist or if the import path is malformed.
+	// On the other hand, don't include a position if the problem is with the imported package,
+	// for example there are no Go files (NoGoError), or there's a problem in the imported
+	// package's source files themselves.
+	//
+	// TODO(matloob): Perhaps make each of those the errors in the first group
+	// (including modload.ImportMissingError, and the corresponding
+	// "cannot find package %q in any of" GOPATH-mode error
+	// produced in build.(*Context).Import; modload.AmbiguousImportError,
+	// and modload.PackageNotInModuleError; and the malformed module path errors
+	// produced in golang.org/x/mod/module.CheckMod) implement an interface
+	// to make it easier to check for them? That would save us from having to
+	// move the modload errors into this package to avoid a package import cycle,
+	// and from having to export an error type for the errors produced in build.
+	if !isMatchErr && nogoErr != nil {
+		stk.Push(path)
+		defer stk.Pop()
+	}
+
+	// Take only the first error from a scanner.ErrorList. PackageError only
+	// has room for one position, so we report the first error with a position
+	// instead of all of the errors without a position.
+	var pos string
+	if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {
+		scanPos := scanErr[0].Pos
+		scanPos.Filename = base.ShortPath(scanPos.Filename)
+		pos = scanPos.String()
+		err = errors.New(scanErr[0].Msg)
+	}
+
+	p.Error = &PackageError{
+		ImportStack: stk.Copy(),
+		Pos:         pos,
+		Err:         err,
+	}
+
+	if path != stk.Top() {
+		p = setErrorPos(p, importPos)
+	}
+}
+
 // Resolve returns the resolved version of imports,
 // which should be p.TestImports or p.XTestImports, NOT p.Imports.
 // The imports in p.TestImports and p.XTestImports are not recursively
@@ -304,19 +372,16 @@
 
 // A PackageError describes an error loading information about a package.
 type PackageError struct {
-	ImportStack   []string // shortest path from package named on command line to this one
-	Pos           string   // position of error
-	Err           error    // the error itself
-	IsImportCycle bool     // the error is an import cycle
-	Hard          bool     // whether the error is soft or hard; soft errors are ignored in some places
+	ImportStack      []string // shortest path from package named on command line to this one
+	Pos              string   // position of error
+	Err              error    // the error itself
+	IsImportCycle    bool     // the error is an import cycle
+	Hard             bool     // whether the error is soft or hard; soft errors are ignored in some places
+	alwaysPrintStack bool     // whether to always print the ImportStack
 }
 
 func (p *PackageError) Error() string {
-	// Import cycles deserve special treatment.
-	if p.IsImportCycle {
-		return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports "))
-	}
-	if p.Pos != "" {
+	if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) {
 		// Omit import stack. The full path to the file where the error
 		// is the most important thing.
 		return p.Pos + ": " + p.Err.Error()
@@ -328,17 +393,18 @@
 	// last path on the stack, we don't omit the path. An error like
 	// "package A imports B: error loading C caused by B" would not be clearer
 	// if "imports B" were omitted.
-	stack := p.ImportStack
-	var ierr ImportPathError
-	if len(stack) > 0 && errors.As(p.Err, &ierr) && ierr.ImportPath() == stack[len(stack)-1] {
-		stack = stack[:len(stack)-1]
-	}
-	if len(stack) == 0 {
+	if len(p.ImportStack) == 0 {
 		return p.Err.Error()
 	}
-	return "package " + strings.Join(stack, "\n\timports ") + ": " + p.Err.Error()
+	var optpos string
+	if p.Pos != "" {
+		optpos = "\n\t" + p.Pos
+	}
+	return "package " + strings.Join(p.ImportStack, "\n\timports ") + optpos + ": " + p.Err.Error()
 }
 
+func (p *PackageError) Unwrap() error { return p.Err }
+
 // PackageError implements MarshalJSON so that Err is marshaled as a string
 // and non-essential fields are omitted.
 func (p *PackageError) MarshalJSON() ([]byte, error) {
@@ -409,6 +475,13 @@
 	return append([]string{}, *s...)
 }
 
+func (s *ImportStack) Top() string {
+	if len(*s) == 0 {
+		return ""
+	}
+	return (*s)[len(*s)-1]
+}
+
 // shorterThan reports whether sp is shorter than t.
 // We use this to record the shortest import sequence
 // that leads to a particular package.
@@ -536,9 +609,6 @@
 		panic("LoadImport called with empty package path")
 	}
 
-	stk.Push(path)
-	defer stk.Pop()
-
 	var parentPath, parentRoot string
 	parentIsStd := false
 	if parent != nil {
@@ -551,6 +621,11 @@
 		pre.preloadImports(bp.Imports, bp)
 	}
 	if bp == nil {
+		if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path {
+			// Only add path to the error's import stack if it's not already present on the error.
+			stk.Push(path)
+			defer stk.Pop()
+		}
 		return &Package{
 			PackagePublic: PackagePublic{
 				ImportPath: path,
@@ -565,7 +640,9 @@
 	importPath := bp.ImportPath
 	p := packageCache[importPath]
 	if p != nil {
+		stk.Push(path)
 		p = reusePackage(p, stk)
+		stk.Pop()
 	} else {
 		p = new(Package)
 		p.Internal.Local = build.IsLocalImport(path)
@@ -575,17 +652,15 @@
 		// Load package.
 		// loadPackageData may return bp != nil even if an error occurs,
 		// in order to return partial information.
-		p.load(stk, bp, err)
-		if p.Error != nil && p.Error.Pos == "" {
-			p = setErrorPos(p, importPos)
-		}
+		p.load(path, stk, importPos, bp, err)
 
 		if !cfg.ModulesEnabled && path != cleanImport(path) {
 			p.Error = &PackageError{
 				ImportStack: stk.Copy(),
-				Err:         fmt.Errorf("non-canonical import path: %q should be %q", path, pathpkg.Clean(path)),
+				Err:         ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)),
 			}
 			p.Incomplete = true
+			setErrorPos(p, importPos)
 		}
 	}
 
@@ -594,7 +669,7 @@
 		return setErrorPos(perr, importPos)
 	}
 	if mode&ResolveImport != 0 {
-		if perr := disallowVendor(srcDir, path, p, stk); perr != p {
+		if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != p {
 			return setErrorPos(perr, importPos)
 		}
 	}
@@ -1232,7 +1307,7 @@
 	// as if it were generated into the testing directory tree
 	// (it's actually in a temporary directory outside any Go tree).
 	// This cleans up a former kludge in passing functionality to the testing package.
-	if strings.HasPrefix(p.ImportPath, "testing/internal") && len(*stk) >= 2 && (*stk)[len(*stk)-2] == "testmain" {
+	if str.HasPathPrefix(p.ImportPath, "testing/internal") && importerPath == "testmain" {
 		return p
 	}
 
@@ -1254,11 +1329,10 @@
 		return p
 	}
 
-	// The stack includes p.ImportPath.
-	// If that's the only thing on the stack, we started
+	// importerPath is empty: we started
 	// with a name given on the command line, not an
 	// import. Anything listed on the command line is fine.
-	if len(*stk) == 1 {
+	if importerPath == "" {
 		return p
 	}
 
@@ -1307,8 +1381,9 @@
 	// Internal is present, and srcDir is outside parent's tree. Not allowed.
 	perr := *p
 	perr.Error = &PackageError{
-		ImportStack: stk.Copy(),
-		Err:         ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"),
+		alwaysPrintStack: true,
+		ImportStack:      stk.Copy(),
+		Err:              ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"),
 	}
 	perr.Incomplete = true
 	return &perr
@@ -1336,16 +1411,15 @@
 // disallowVendor checks that srcDir is allowed to import p as path.
 // If the import is allowed, disallowVendor returns the original package p.
 // If not, it returns a new package containing just an appropriate error.
-func disallowVendor(srcDir string, path string, p *Package, stk *ImportStack) *Package {
-	// The stack includes p.ImportPath.
-	// If that's the only thing on the stack, we started
+func disallowVendor(srcDir string, path string, importerPath string, p *Package, stk *ImportStack) *Package {
+	// If the importerPath is empty, we started
 	// with a name given on the command line, not an
 	// import. Anything listed on the command line is fine.
-	if len(*stk) == 1 {
+	if importerPath == "" {
 		return p
 	}
 
-	if perr := disallowVendorVisibility(srcDir, p, stk); perr != p {
+	if perr := disallowVendorVisibility(srcDir, p, importerPath, stk); perr != p {
 		return perr
 	}
 
@@ -1368,12 +1442,12 @@
 // is not subject to the rules, only subdirectories of vendor.
 // This allows people to have packages and commands named vendor,
 // for maximal compatibility with existing source trees.
-func disallowVendorVisibility(srcDir string, p *Package, stk *ImportStack) *Package {
-	// The stack includes p.ImportPath.
-	// If that's the only thing on the stack, we started
+func disallowVendorVisibility(srcDir string, p *Package, importerPath string, stk *ImportStack) *Package {
+	// The stack does not include p.ImportPath.
+	// If there's nothing on the stack, we started
 	// with a name given on the command line, not an
 	// import. Anything listed on the command line is fine.
-	if len(*stk) == 1 {
+	if importerPath == "" {
 		return p
 	}
 
@@ -1517,7 +1591,8 @@
 
 // load populates p using information from bp, err, which should
 // be the result of calling build.Context.Import.
-func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
+// stk contains the import stack, not including path itself.
+func (p *Package) load(path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {
 	p.copyBuild(bp)
 
 	// The localPrefix is the path we interpret ./ imports relative to.
@@ -1535,21 +1610,22 @@
 				ImportStack: stk.Copy(),
 				Err:         err,
 			}
+
+			// Add the importer's position information if the import position exists, and
+			// the current package being examined is the importer.
+			// If we have not yet accepted package p onto the import stack,
+			// then the cause of the error is not within p itself: the error
+			// must be either in an explicit command-line argument,
+			// or on the importer side (indicated by a non-empty importPos).
+			if path != stk.Top() && len(importPos) > 0 {
+				p = setErrorPos(p, importPos)
+			}
 		}
 	}
 
 	if err != nil {
-		if _, ok := err.(*build.NoGoError); ok {
-			err = &NoGoError{Package: p}
-		}
 		p.Incomplete = true
-
-		setError(base.ExpandScanner(err))
-		if _, isScanErr := err.(scanner.ErrorList); !isScanErr {
-			return
-		}
-		// Fall through if there was an error parsing a file. 'go list -e' should
-		// still report imports and other metadata.
+		p.setLoadPackageDataError(err, path, stk, importPos)
 	}
 
 	useBindir := p.Name == "main"
@@ -1563,6 +1639,8 @@
 	if useBindir {
 		// Report an error when the old code.google.com/p/go.tools paths are used.
 		if InstallTargetDir(p) == StalePath {
+			// TODO(matloob): remove this branch, and StalePath itself. code.google.com/p/go is so
+			// old, even this code checking for it is stale now!
 			newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1)
 			e := ImportErrorf(p.ImportPath, "the %v command has moved; use %v instead.", p.ImportPath, newPath)
 			setError(e)
@@ -1671,6 +1749,23 @@
 		}
 	}
 
+	// Check for case-insensitive collisions of import paths.
+	fold := str.ToFold(p.ImportPath)
+	if other := foldPath[fold]; other == "" {
+		foldPath[fold] = p.ImportPath
+	} else if other != p.ImportPath {
+		setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other))
+		return
+	}
+
+	if !SafeArg(p.ImportPath) {
+		setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))
+		return
+	}
+
+	stk.Push(path)
+	defer stk.Pop()
+
 	// Check for case-insensitive collision of input files.
 	// To avoid problems on case-insensitive files, we reject any package
 	// where two different input files have equal names under a case-insensitive
@@ -1699,10 +1794,6 @@
 		setError(fmt.Errorf("invalid input directory name %q", name))
 		return
 	}
-	if !SafeArg(p.ImportPath) {
-		setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))
-		return
-	}
 
 	// Build list of imported packages and full dependency list.
 	imports := make([]*Package, 0, len(p.Imports))
@@ -1766,15 +1857,6 @@
 		return
 	}
 
-	// Check for case-insensitive collisions of import paths.
-	fold := str.ToFold(p.ImportPath)
-	if other := foldPath[fold]; other == "" {
-		foldPath[fold] = p.ImportPath
-	} else if other != p.ImportPath {
-		setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other))
-		return
-	}
-
 	if cfg.ModulesEnabled && p.Error == nil {
 		mainPath := p.ImportPath
 		if p.Internal.CmdlineFiles {
@@ -1877,10 +1959,11 @@
 	// Some targets must use external linking even inside GOROOT.
 	switch cfg.BuildContext.GOOS {
 	case "android":
-		return true
+		if cfg.BuildContext.GOARCH != "arm64" {
+			return true
+		}
 	case "darwin":
-		switch cfg.BuildContext.GOARCH {
-		case "arm", "arm64":
+		if cfg.BuildContext.GOARCH == "arm64" {
 			return true
 		}
 	}
@@ -1938,13 +2021,22 @@
 // using absolute paths. "Possibly relevant" means that files are not excluded
 // due to build tags, but files with names beginning with . or _ are still excluded.
 func (p *Package) InternalAllGoFiles() []string {
-	var extra []string
+	return p.mkAbs(str.StringList(p.constraintIgnoredGoFiles(), p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
+}
+
+// constraintIgnoredGoFiles returns the list of Go files ignored for reasons
+// other than having a name beginning with '.' or '_'.
+func (p *Package) constraintIgnoredGoFiles() []string {
+	if len(p.IgnoredGoFiles) == 0 {
+		return nil
+	}
+	files := make([]string, 0, len(p.IgnoredGoFiles))
 	for _, f := range p.IgnoredGoFiles {
-		if f != "" && f[0] != '.' || f[0] != '_' {
-			extra = append(extra, f)
+		if f != "" && f[0] != '.' && f[0] != '_' {
+			files = append(files, f)
 		}
 	}
-	return p.mkAbs(str.StringList(extra, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
+	return files
 }
 
 // usesSwig reports whether the package needs to run SWIG.
@@ -2038,7 +2130,7 @@
 	var pkgs []*Package
 	for _, pkg := range PackagesAndErrors(args) {
 		if pkg.Error != nil {
-			base.Errorf("can't load package: %s", pkg.Error)
+			base.Errorf("%v", pkg.Error)
 			continue
 		}
 		pkgs = append(pkgs, pkg)
@@ -2078,13 +2170,13 @@
 	for _, m := range matches {
 		for _, pkg := range m.Pkgs {
 			if pkg == "" {
-				panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern))
+				panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern()))
 			}
 			p := loadImport(pre, pkg, base.Cwd, nil, &stk, nil, 0)
-			p.Match = append(p.Match, m.Pattern)
+			p.Match = append(p.Match, m.Pattern())
 			p.Internal.CmdlinePkg = true
-			if m.Literal {
-				// Note: do not set = m.Literal unconditionally
+			if m.IsLiteral() {
+				// Note: do not set = m.IsLiteral unconditionally
 				// because maybe we'll see p matching both
 				// a literal and also a non-literal pattern.
 				p.Internal.CmdlinePkgLiteral = true
@@ -2095,6 +2187,25 @@
 			seenPkg[p] = true
 			pkgs = append(pkgs, p)
 		}
+
+		if len(m.Errs) > 0 {
+			// In addition to any packages that were actually resolved from the
+			// pattern, there was some error in resolving the pattern itself.
+			// Report it as a synthetic package.
+			p := new(Package)
+			p.ImportPath = m.Pattern()
+			// Pass an empty ImportStack and nil importPos: the error arose from a pattern, not an import.
+			var stk ImportStack
+			var importPos []token.Position
+			p.setLoadPackageDataError(m.Errs[0], m.Pattern(), &stk, importPos)
+			p.Incomplete = true
+			p.Match = append(p.Match, m.Pattern())
+			p.Internal.CmdlinePkg = true
+			if m.IsLiteral() {
+				p.Internal.CmdlinePkgLiteral = true
+			}
+			pkgs = append(pkgs, p)
+		}
 	}
 
 	// Now that CmdlinePkg is set correctly,
@@ -2130,7 +2241,7 @@
 	printed := map[*PackageError]bool{}
 	for _, pkg := range pkgs {
 		if pkg.Error != nil {
-			base.Errorf("can't load package: %s", pkg.Error)
+			base.Errorf("%v", pkg.Error)
 			printed[pkg.Error] = true
 		}
 		for _, err := range pkg.DepsErrors {
@@ -2140,7 +2251,7 @@
 			// Only print each once.
 			if !printed[err] {
 				printed[err] = true
-				base.Errorf("%s", err)
+				base.Errorf("%v", err)
 			}
 		}
 	}
@@ -2232,9 +2343,7 @@
 	pkg := new(Package)
 	pkg.Internal.Local = true
 	pkg.Internal.CmdlineFiles = true
-	stk.Push("main")
-	pkg.load(&stk, bp, err)
-	stk.Pop()
+	pkg.load("command-line-arguments", &stk, nil, bp, err)
 	pkg.Internal.LocalPrefix = dirToImportPath(dir)
 	pkg.ImportPath = "command-line-arguments"
 	pkg.Target = ""
diff --git a/libgo/go/cmd/go/internal/load/test.go b/libgo/go/cmd/go/internal/load/test.go
index fefc7d2..6d251e8 100644
--- a/libgo/go/cmd/go/internal/load/test.go
+++ b/libgo/go/cmd/go/internal/load/test.go
@@ -6,7 +6,6 @@
 
 import (
 	"bytes"
-	"cmd/go/internal/base"
 	"cmd/go/internal/str"
 	"errors"
 	"fmt"
@@ -26,6 +25,7 @@
 var TestMainDeps = []string{
 	// Dependencies for testmain.
 	"os",
+	"reflect",
 	"testing",
 	"testing/internal/testdeps",
 }
@@ -55,7 +55,6 @@
 		}
 		if len(p1.DepsErrors) > 0 {
 			perr := p1.DepsErrors[0]
-			perr.Pos = "" // show full import stack
 			err = perr
 			break
 		}
@@ -271,7 +270,7 @@
 	// afterward that gathers t.Cover information.
 	t, err := loadTestFuncs(ptest)
 	if err != nil && pmain.Error == nil {
-		pmain.Error = &PackageError{Err: err}
+		pmain.setLoadPackageDataError(err, p.ImportPath, &stk, nil)
 	}
 	t.Cover = cover
 	if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 {
@@ -540,7 +539,7 @@
 func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error {
 	f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments)
 	if err != nil {
-		return base.ExpandScanner(err)
+		return err
 	}
 	for _, d := range f.Decls {
 		n, ok := d.(*ast.FuncDecl)
@@ -612,8 +611,9 @@
 package main
 
 import (
-{{if not .TestMain}}
 	"os"
+{{if .TestMain}}
+	"reflect"
 {{end}}
 	"testing"
 	"testing/internal/testdeps"
@@ -704,6 +704,7 @@
 	m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, examples)
 {{with .TestMain}}
 	{{.Package}}.{{.Name}}(m)
+	os.Exit(int(reflect.ValueOf(m).Elem().FieldByName("exitCode").Int()))
 {{else}}
 	os.Exit(m.Run())
 {{end}}
diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
index a14362b..c3e09bb 100644
--- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
+++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
@@ -13,19 +13,19 @@
 // or an F_OFD_SETLK command for 'fcntl', that allows for better concurrency and
 // does not require per-inode bookkeeping in the application.
 //
-// TODO(bcmills): If we add a build tag for Illumos (see golang.org/issue/20603)
-// then Illumos should use F_OFD_SETLK, and the resulting code would be as
-// simple as filelock_unix.go. We will still need the code in this file for AIX
-// or as long as Oracle Solaris provides only F_SETLK.
+// TODO(golang.org/issue/35618): add a syscall.Flock binding for Illumos and
+// switch it over to use filelock_unix.go.
 
 package filelock
 
 import (
 	"errors"
 	"io"
+	"math/rand"
 	"os"
 	"sync"
 	"syscall"
+	"time"
 )
 
 type lockType int16
@@ -93,7 +93,67 @@
 		wait <- f
 	}
 
-	err = setlkw(f.Fd(), lt)
+	// Spurious EDEADLK errors arise on platforms that compute deadlock graphs at
+	// the process, rather than thread, level. Consider processes P and Q, with
+	// threads P.1, P.2, and Q.3. The following trace is NOT a deadlock, but will be
+	// reported as a deadlock on systems that consider only process granularity:
+	//
+	// 	P.1 locks file A.
+	// 	Q.3 locks file B.
+	// 	Q.3 blocks on file A.
+	// 	P.2 blocks on file B. (This is erroneously reported as a deadlock.)
+	// 	P.1 unlocks file A.
+	// 	Q.3 unblocks and locks file A.
+	// 	Q.3 unlocks files A and B.
+	// 	P.2 unblocks and locks file B.
+	// 	P.2 unlocks file B.
+	//
+	// These spurious errors were observed in practice on AIX and Solaris in
+	// cmd/go: see https://golang.org/issue/32817.
+	//
+	// We work around this bug by treating EDEADLK as always spurious. If there
+	// really is a lock-ordering bug between the interacting processes, it will
+	// become a livelock instead, but that's not appreciably worse than if we had
+	// a proper flock implementation (which generally does not even attempt to
+	// diagnose deadlocks).
+	//
+	// In the above example, that changes the trace to:
+	//
+	// 	P.1 locks file A.
+	// 	Q.3 locks file B.
+	// 	Q.3 blocks on file A.
+	// 	P.2 spuriously fails to lock file B and goes to sleep.
+	// 	P.1 unlocks file A.
+	// 	Q.3 unblocks and locks file A.
+	// 	Q.3 unlocks files A and B.
+	// 	P.2 wakes up and locks file B.
+	// 	P.2 unlocks file B.
+	//
+	// We know that the retry loop will not introduce a *spurious* livelock
+	// because, according to the POSIX specification, EDEADLK is only to be
+	// returned when “the lock is blocked by a lock from another process”.
+	// If that process is blocked on some lock that we are holding, then the
+	// resulting livelock is due to a real deadlock (and would manifest as such
+	// when using, for example, the flock implementation of this package).
+	// If the other process is *not* blocked on some other lock that we are
+	// holding, then it will eventually release the requested lock.
+
+	nextSleep := 1 * time.Millisecond
+	const maxSleep = 500 * time.Millisecond
+	for {
+		err = setlkw(f.Fd(), lt)
+		if err != syscall.EDEADLK {
+			break
+		}
+		time.Sleep(nextSleep)
+
+		nextSleep += nextSleep
+		if nextSleep > maxSleep {
+			nextSleep = maxSleep
+		}
+		// Apply 10% jitter to avoid synchronizing collisions when we finally unblock.
+		nextSleep += time.Duration((0.1*rand.Float64() - 0.05) * float64(nextSleep))
+	}
 
 	if err != nil {
 		unlock(f)
diff --git a/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go b/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go
index 8f7a7d5..416c69d 100644
--- a/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go
+++ b/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go
@@ -8,8 +8,11 @@
 package lockedfile_test
 
 import (
+	"fmt"
+	"internal/testenv"
 	"io/ioutil"
 	"os"
+	"os/exec"
 	"path/filepath"
 	"testing"
 	"time"
@@ -172,3 +175,98 @@
 	f.Close()
 	wait(t)
 }
+
+// TestSpuriousEDEADLK verifies that the spurious EDEADLK reported in
+// https://golang.org/issue/32817 no longer occurs.
+func TestSpuriousEDEADLK(t *testing.T) {
+	// 	P.1 locks file A.
+	// 	Q.3 locks file B.
+	// 	Q.3 blocks on file A.
+	// 	P.2 blocks on file B. (Spurious EDEADLK occurs here.)
+	// 	P.1 unlocks file A.
+	// 	Q.3 unblocks and locks file A.
+	// 	Q.3 unlocks files A and B.
+	// 	P.2 unblocks and locks file B.
+	// 	P.2 unlocks file B.
+
+	testenv.MustHaveExec(t)
+
+	dirVar := t.Name() + "DIR"
+
+	if dir := os.Getenv(dirVar); dir != "" {
+		// Q.3 locks file B.
+		b, err := lockedfile.Edit(filepath.Join(dir, "B"))
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer b.Close()
+
+		if err := ioutil.WriteFile(filepath.Join(dir, "locked"), []byte("ok"), 0666); err != nil {
+			t.Fatal(err)
+		}
+
+		// Q.3 blocks on file A.
+		a, err := lockedfile.Edit(filepath.Join(dir, "A"))
+		// Q.3 unblocks and locks file A.
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer a.Close()
+
+		// Q.3 unlocks files A and B.
+		return
+	}
+
+	dir, remove := mustTempDir(t)
+	defer remove()
+
+	// P.1 locks file A.
+	a, err := lockedfile.Edit(filepath.Join(dir, "A"))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	cmd := exec.Command(os.Args[0], "-test.run="+t.Name())
+	cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", dirVar, dir))
+
+	qDone := make(chan struct{})
+	waitQ := mustBlock(t, "Edit A and B in subprocess", func() {
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			t.Errorf("%v:\n%s", err, out)
+		}
+		close(qDone)
+	})
+
+	// Wait until process Q has either failed or locked file B.
+	// Otherwise, P.2 might not block on file B as intended.
+locked:
+	for {
+		if _, err := os.Stat(filepath.Join(dir, "locked")); !os.IsNotExist(err) {
+			break locked
+		}
+		select {
+		case <-qDone:
+			break locked
+		case <-time.After(1 * time.Millisecond):
+		}
+	}
+
+	waitP2 := mustBlock(t, "Edit B", func() {
+		// P.2 blocks on file B. (Spurious EDEADLK occurs here.)
+		b, err := lockedfile.Edit(filepath.Join(dir, "B"))
+		// P.2 unblocks and locks file B.
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		// P.2 unlocks file B.
+		b.Close()
+	})
+
+	// P.1 unlocks file A.
+	a.Close()
+
+	waitQ(t)
+	waitP2(t)
+}
diff --git a/libgo/go/cmd/go/internal/modcmd/download.go b/libgo/go/cmd/go/internal/modcmd/download.go
index 7d5294d..5844349 100644
--- a/libgo/go/cmd/go/internal/modcmd/download.go
+++ b/libgo/go/cmd/go/internal/modcmd/download.go
@@ -24,7 +24,8 @@
 	Long: `
 Download downloads the named modules, which can be module patterns selecting
 dependencies of the main module or module queries of the form path@version.
-With no arguments, download applies to all dependencies of the main module.
+With no arguments, download applies to all dependencies of the main module
+(equivalent to 'go mod download all').
 
 The go command will automatically download modules as needed during ordinary
 execution. The "go mod download" command is useful mainly for pre-filling
diff --git a/libgo/go/cmd/go/internal/modcmd/vendor.go b/libgo/go/cmd/go/internal/modcmd/vendor.go
index 0c00d12..8509ceb 100644
--- a/libgo/go/cmd/go/internal/modcmd/vendor.go
+++ b/libgo/go/cmd/go/internal/modcmd/vendor.go
@@ -123,6 +123,11 @@
 		fmt.Fprintf(os.Stderr, "go: no dependencies to vendor\n")
 		return
 	}
+
+	if err := os.MkdirAll(vdir, 0777); err != nil {
+		base.Fatalf("go mod vendor: %v", err)
+	}
+
 	if err := ioutil.WriteFile(filepath.Join(vdir, "modules.txt"), buf.Bytes(), 0666); err != nil {
 		base.Fatalf("go mod vendor: %v", err)
 	}
diff --git a/libgo/go/cmd/go/internal/modcmd/verify.go b/libgo/go/cmd/go/internal/modcmd/verify.go
index ac3f135..b7fd7fa 100644
--- a/libgo/go/cmd/go/internal/modcmd/verify.go
+++ b/libgo/go/cmd/go/internal/modcmd/verify.go
@@ -10,6 +10,7 @@
 	"fmt"
 	"io/ioutil"
 	"os"
+	"runtime"
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
@@ -52,17 +53,41 @@
 			base.Fatalf("go: cannot find main module; see 'go help modules'")
 		}
 	}
+
+	// Only verify up to GOMAXPROCS zips at once.
+	type token struct{}
+	sem := make(chan token, runtime.GOMAXPROCS(0))
+
+	// Use a slice of result channels, so that the output is deterministic.
+	mods := modload.LoadBuildList()[1:]
+	errsChans := make([]<-chan []error, len(mods))
+
+	for i, mod := range mods {
+		sem <- token{}
+		errsc := make(chan []error, 1)
+		errsChans[i] = errsc
+		mod := mod // use a copy to avoid data races
+		go func() {
+			errsc <- verifyMod(mod)
+			<-sem
+		}()
+	}
+
 	ok := true
-	for _, mod := range modload.LoadBuildList()[1:] {
-		ok = verifyMod(mod) && ok
+	for _, errsc := range errsChans {
+		errs := <-errsc
+		for _, err := range errs {
+			base.Errorf("%s", err)
+			ok = false
+		}
 	}
 	if ok {
 		fmt.Printf("all modules verified\n")
 	}
 }
 
-func verifyMod(mod module.Version) bool {
-	ok := true
+func verifyMod(mod module.Version) []error {
+	var errs []error
 	zip, zipErr := modfetch.CachePath(mod, "zip")
 	if zipErr == nil {
 		_, zipErr = os.Stat(zip)
@@ -73,10 +98,10 @@
 		if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) &&
 			dirErr != nil && errors.Is(dirErr, os.ErrNotExist) {
 			// Nothing downloaded yet. Nothing to verify.
-			return true
+			return nil
 		}
-		base.Errorf("%s %s: missing ziphash: %v", mod.Path, mod.Version, err)
-		return false
+		errs = append(errs, fmt.Errorf("%s %s: missing ziphash: %v", mod.Path, mod.Version, err))
+		return errs
 	}
 	h := string(bytes.TrimSpace(data))
 
@@ -85,11 +110,10 @@
 	} else {
 		hZ, err := dirhash.HashZip(zip, dirhash.DefaultHash)
 		if err != nil {
-			base.Errorf("%s %s: %v", mod.Path, mod.Version, err)
-			return false
+			errs = append(errs, fmt.Errorf("%s %s: %v", mod.Path, mod.Version, err))
+			return errs
 		} else if hZ != h {
-			base.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip)
-			ok = false
+			errs = append(errs, fmt.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip))
 		}
 	}
 	if dirErr != nil && errors.Is(dirErr, os.ErrNotExist) {
@@ -98,13 +122,12 @@
 		hD, err := dirhash.HashDir(dir, mod.Path+"@"+mod.Version, dirhash.DefaultHash)
 		if err != nil {
 
-			base.Errorf("%s %s: %v", mod.Path, mod.Version, err)
-			return false
+			errs = append(errs, fmt.Errorf("%s %s: %v", mod.Path, mod.Version, err))
+			return errs
 		}
 		if hD != h {
-			base.Errorf("%s %s: dir has been modified (%v)", mod.Path, mod.Version, dir)
-			ok = false
+			errs = append(errs, fmt.Errorf("%s %s: dir has been modified (%v)", mod.Path, mod.Version, dir))
 		}
 	}
-	return ok
+	return errs
 }
diff --git a/libgo/go/cmd/go/internal/modconv/convert_test.go b/libgo/go/cmd/go/internal/modconv/convert_test.go
index a2a2601..a04a13b 100644
--- a/libgo/go/cmd/go/internal/modconv/convert_test.go
+++ b/libgo/go/cmd/go/internal/modconv/convert_test.go
@@ -18,7 +18,6 @@
 
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/modfetch"
-	"cmd/go/internal/modfetch/codehost"
 
 	"golang.org/x/mod/modfile"
 	"golang.org/x/mod/module"
@@ -42,8 +41,7 @@
 		log.Fatal(err)
 	}
 	defer os.RemoveAll(dir)
-	modfetch.PkgMod = filepath.Join(dir, "pkg/mod")
-	codehost.WorkRoot = filepath.Join(dir, "codework")
+	cfg.GOMODCACHE = filepath.Join(dir, "pkg/mod")
 
 	return m.Run()
 }
diff --git a/libgo/go/cmd/go/internal/modfetch/cache.go b/libgo/go/cmd/go/internal/modfetch/cache.go
index d6ff068..e3074b7 100644
--- a/libgo/go/cmd/go/internal/modfetch/cache.go
+++ b/libgo/go/cmd/go/internal/modfetch/cache.go
@@ -26,17 +26,17 @@
 	"golang.org/x/mod/semver"
 )
 
-var PkgMod string // $GOPATH/pkg/mod; set by package modload
-
 func cacheDir(path string) (string, error) {
-	if PkgMod == "" {
-		return "", fmt.Errorf("internal error: modfetch.PkgMod not set")
+	if cfg.GOMODCACHE == "" {
+		// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
+		// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.
+		return "", fmt.Errorf("internal error: cfg.GOMODCACHE not set")
 	}
 	enc, err := module.EscapePath(path)
 	if err != nil {
 		return "", err
 	}
-	return filepath.Join(PkgMod, "cache/download", enc, "/@v"), nil
+	return filepath.Join(cfg.GOMODCACHE, "cache/download", enc, "/@v"), nil
 }
 
 func CachePath(m module.Version, suffix string) (string, error) {
@@ -63,8 +63,10 @@
 // along with the directory if the directory does not exist or if the directory
 // is not completely populated.
 func DownloadDir(m module.Version) (string, error) {
-	if PkgMod == "" {
-		return "", fmt.Errorf("internal error: modfetch.PkgMod not set")
+	if cfg.GOMODCACHE == "" {
+		// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
+		// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.
+		return "", fmt.Errorf("internal error: cfg.GOMODCACHE not set")
 	}
 	enc, err := module.EscapePath(m.Path)
 	if err != nil {
@@ -81,7 +83,7 @@
 		return "", err
 	}
 
-	dir := filepath.Join(PkgMod, enc+"@"+encVer)
+	dir := filepath.Join(cfg.GOMODCACHE, enc+"@"+encVer)
 	if fi, err := os.Stat(dir); os.IsNotExist(err) {
 		return dir, err
 	} else if err != nil {
@@ -131,11 +133,13 @@
 // user's working directory.
 // If err is nil, the caller MUST eventually call the unlock function.
 func SideLock() (unlock func(), err error) {
-	if PkgMod == "" {
-		base.Fatalf("go: internal error: modfetch.PkgMod not set")
+	if cfg.GOMODCACHE == "" {
+		// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
+		// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.
+		base.Fatalf("go: internal error: cfg.GOMODCACHE not set")
 	}
 
-	path := filepath.Join(PkgMod, "cache", "lock")
+	path := filepath.Join(cfg.GOMODCACHE, "cache", "lock")
 	if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
 		return nil, fmt.Errorf("failed to create cache directory: %w", err)
 	}
@@ -456,7 +460,7 @@
 // just to find out about a commit we already know about
 // (and have cached under its pseudo-version).
 func readDiskStatByHash(path, rev string) (file string, info *RevInfo, err error) {
-	if PkgMod == "" {
+	if cfg.GOMODCACHE == "" {
 		// Do not download to current directory.
 		return "", nil, errNotCached
 	}
diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go
index 5867288..d85eddf 100644
--- a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go
+++ b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go
@@ -153,15 +153,11 @@
 	return rev
 }
 
-// WorkRoot is the root of the cached work directory.
-// It is set by cmd/go/internal/modload.InitMod.
-var WorkRoot string
-
 // WorkDir returns the name of the cached work directory to use for the
 // given repository type and name.
 func WorkDir(typ, name string) (dir, lockfile string, err error) {
-	if WorkRoot == "" {
-		return "", "", fmt.Errorf("codehost.WorkRoot not set")
+	if cfg.GOMODCACHE == "" {
+		return "", "", fmt.Errorf("neither GOPATH nor GOMODCACHE are set")
 	}
 
 	// We name the work directory for the SHA256 hash of the type and name.
@@ -173,7 +169,7 @@
 		return "", "", fmt.Errorf("codehost.WorkDir: type cannot contain colon")
 	}
 	key := typ + ":" + name
-	dir = filepath.Join(WorkRoot, fmt.Sprintf("%x", sha256.Sum256([]byte(key))))
+	dir = filepath.Join(cfg.GOMODCACHE, "cache/vcs", fmt.Sprintf("%x", sha256.Sum256([]byte(key))))
 
 	if cfg.BuildX {
 		fmt.Fprintf(os.Stderr, "mkdir -p %s # %s %s\n", filepath.Dir(dir), typ, name)
diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/git.go b/libgo/go/cmd/go/internal/modfetch/codehost/git.go
index f08df51..3192132 100644
--- a/libgo/go/cmd/go/internal/modfetch/codehost/git.go
+++ b/libgo/go/cmd/go/internal/modfetch/codehost/git.go
@@ -27,11 +27,6 @@
 	"golang.org/x/mod/semver"
 )
 
-// GitRepo returns the code repository at the given Git remote reference.
-func GitRepo(remote string) (Repo, error) {
-	return newGitRepoCached(remote, false)
-}
-
 // LocalGitRepo is like Repo but accepts both Git remote references
 // and paths to repositories on the local file system.
 func LocalGitRepo(remote string) (Repo, error) {
diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go b/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go
index cc32a1e..ba27c70 100644
--- a/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go
+++ b/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go
@@ -57,7 +57,6 @@
 		log.Fatal(err)
 	}
 	defer os.RemoveAll(dir)
-	WorkRoot = dir
 
 	if testenv.HasExternalNetwork() && testenv.HasExec() {
 		// Clone gitrepo1 into a local directory.
diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/shell.go b/libgo/go/cmd/go/internal/modfetch/codehost/shell.go
index 835bc53..2762c55 100644
--- a/libgo/go/cmd/go/internal/modfetch/codehost/shell.go
+++ b/libgo/go/cmd/go/internal/modfetch/codehost/shell.go
@@ -20,6 +20,7 @@
 	"strings"
 	"time"
 
+	"cmd/go/internal/cfg"
 	"cmd/go/internal/modfetch/codehost"
 )
 
@@ -29,7 +30,7 @@
 }
 
 func main() {
-	codehost.WorkRoot = "/tmp/vcswork"
+	cfg.GOMODCACHE = "/tmp/vcswork"
 	log.SetFlags(0)
 	log.SetPrefix("shell: ")
 	flag.Usage = usage
diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo.go b/libgo/go/cmd/go/internal/modfetch/coderepo.go
index d1d24a4..d043903 100644
--- a/libgo/go/cmd/go/internal/modfetch/coderepo.go
+++ b/libgo/go/cmd/go/internal/modfetch/coderepo.go
@@ -563,7 +563,7 @@
 		return err
 	}
 	if !t.Equal(info.Time.Truncate(time.Second)) {
-		return fmt.Errorf("does not match version-control timestamp (%s)", info.Time.UTC().Format(time.RFC3339))
+		return fmt.Errorf("does not match version-control timestamp (expected %s)", info.Time.UTC().Format(pseudoVersionTimestampFormat))
 	}
 
 	tagPrefix := ""
@@ -1012,28 +1012,3 @@
 		return s[len(prefix)] == '/' && s[:len(prefix)] == prefix
 	}
 }
-
-func isVendoredPackage(name string) bool {
-	var i int
-	if strings.HasPrefix(name, "vendor/") {
-		i += len("vendor/")
-	} else if j := strings.Index(name, "/vendor/"); j >= 0 {
-		// This offset looks incorrect; this should probably be
-		//
-		// 	i = j + len("/vendor/")
-		//
-		// (See https://golang.org/issue/31562.)
-		//
-		// Unfortunately, we can't fix it without invalidating checksums.
-		// Fortunately, the error appears to be strictly conservative: we'll retain
-		// vendored packages that we should have pruned, but we won't prune
-		// non-vendored packages that we should have retained.
-		//
-		// Since this defect doesn't seem to break anything, it's not worth fixing
-		// for now.
-		i += len("/vendor/")
-	} else {
-		return false
-	}
-	return strings.Contains(name[i:], "/")
-}
diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go
index 3983094..f69c193 100644
--- a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go
+++ b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go
@@ -44,7 +44,7 @@
 	}
 	defer os.RemoveAll(dir)
 
-	codehost.WorkRoot = dir
+	cfg.GOMODCACHE = dir
 	return m.Run()
 }
 
diff --git a/libgo/go/cmd/go/internal/modfetch/fetch.go b/libgo/go/cmd/go/internal/modfetch/fetch.go
index aadf883..fd7a5ce 100644
--- a/libgo/go/cmd/go/internal/modfetch/fetch.go
+++ b/libgo/go/cmd/go/internal/modfetch/fetch.go
@@ -35,9 +35,10 @@
 // local download cache and returns the name of the directory
 // corresponding to the root of the module's file tree.
 func Download(mod module.Version) (dir string, err error) {
-	if PkgMod == "" {
-		// Do not download to current directory.
-		return "", fmt.Errorf("missing modfetch.PkgMod")
+	if cfg.GOMODCACHE == "" {
+		// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
+		// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.
+		base.Fatalf("go: internal error: cfg.GOMODCACHE not set")
 	}
 
 	// The par.Cache here avoids duplicate work.
@@ -57,11 +58,10 @@
 }
 
 func download(mod module.Version) (dir string, err error) {
-	// If the directory exists, and no .partial file exists,
-	// the module has already been completely extracted.
-	// .partial files may be created when future versions of cmd/go
-	// extract module zip directories in place instead of extracting
-	// to a random temporary directory and renaming.
+	// If the directory exists, and no .partial file exists, the module has
+	// already been completely extracted. .partial files may be created when a
+	// module zip directory is extracted in place instead of being extracted to a
+	// temporary directory and renamed.
 	dir, err = DownloadDir(mod)
 	if err == nil {
 		return dir, nil
@@ -115,31 +115,61 @@
 		return "", err
 	}
 
-	// Extract the zip file to a temporary directory, then rename it to the
-	// final path. That way, we can use the existence of the source directory to
-	// signal that it has been extracted successfully, and if someone deletes
-	// the entire directory (e.g. as an attempt to prune out file corruption)
-	// the module cache will still be left in a recoverable state.
+	// Extract the module zip directory.
+	//
+	// By default, we extract to a temporary directory, then atomically rename to
+	// its final location. We use the existence of the source directory to signal
+	// that it has been extracted successfully (see DownloadDir).  If someone
+	// deletes the entire directory (e.g., as an attempt to prune out file
+	// corruption), the module cache will still be left in a recoverable
+	// state.
+	//
+	// Unfortunately, os.Rename may fail with ERROR_ACCESS_DENIED on Windows if
+	// another process opens files in the temporary directory. This is partially
+	// mitigated by using robustio.Rename, which retries os.Rename for a short
+	// time.
+	//
+	// To avoid this error completely, if unzipInPlace is set, we instead create a
+	// .partial file (indicating the directory isn't fully extracted), then we
+	// extract the directory at its final location, then we delete the .partial
+	// file. This is not the default behavior because older versions of Go may
+	// simply stat the directory to check whether it exists without looking for a
+	// .partial file. If multiple versions run concurrently, the older version may
+	// assume a partially extracted directory is complete.
+	// TODO(golang.org/issue/36568): when these older versions are no longer
+	// supported, remove the old default behavior and the unzipInPlace flag.
 	if err := os.MkdirAll(parentDir, 0777); err != nil {
 		return "", err
 	}
-	tmpDir, err := ioutil.TempDir(parentDir, tmpPrefix)
-	if err != nil {
-		return "", err
-	}
-	defer func() {
-		if err != nil {
-			RemoveAll(tmpDir)
+
+	if unzipInPlace {
+		if err := ioutil.WriteFile(partialPath, nil, 0666); err != nil {
+			return "", err
 		}
-	}()
-
-	if err := modzip.Unzip(tmpDir, mod, zipfile); err != nil {
-		fmt.Fprintf(os.Stderr, "-> %s\n", err)
-		return "", err
-	}
-
-	if err := robustio.Rename(tmpDir, dir); err != nil {
-		return "", err
+		if err := modzip.Unzip(dir, mod, zipfile); err != nil {
+			fmt.Fprintf(os.Stderr, "-> %s\n", err)
+			if rmErr := RemoveAll(dir); rmErr == nil {
+				os.Remove(partialPath)
+			}
+			return "", err
+		}
+		if err := os.Remove(partialPath); err != nil {
+			return "", err
+		}
+	} else {
+		tmpDir, err := ioutil.TempDir(parentDir, tmpPrefix)
+		if err != nil {
+			return "", err
+		}
+		if err := modzip.Unzip(tmpDir, mod, zipfile); err != nil {
+			fmt.Fprintf(os.Stderr, "-> %s\n", err)
+			RemoveAll(tmpDir)
+			return "", err
+		}
+		if err := robustio.Rename(tmpDir, dir); err != nil {
+			RemoveAll(tmpDir)
+			return "", err
+		}
 	}
 
 	if !cfg.ModCacheRW {
@@ -150,6 +180,17 @@
 	return dir, nil
 }
 
+var unzipInPlace bool
+
+func init() {
+	for _, f := range strings.Split(os.Getenv("GODEBUG"), ",") {
+		if f == "modcacheunzipinplace=1" {
+			unzipInPlace = true
+			break
+		}
+	}
+}
+
 var downloadZipCache par.Cache
 
 // DownloadZip downloads the specific module version to the
@@ -321,7 +362,7 @@
 		}
 		return nil
 	})
-	return os.RemoveAll(dir)
+	return robustio.RemoveAll(dir)
 }
 
 var GoSumFile string // path to go.sum; set by package modload
@@ -416,7 +457,7 @@
 
 // checkMod checks the given module's checksum.
 func checkMod(mod module.Version) {
-	if PkgMod == "" {
+	if cfg.GOMODCACHE == "" {
 		// Do not use current directory.
 		return
 	}
@@ -473,6 +514,7 @@
 	goSum.mu.Lock()
 	inited, err := initGoSum()
 	if err != nil {
+		goSum.mu.Unlock()
 		return err
 	}
 	done := inited && haveModSumLocked(mod, h)
@@ -553,7 +595,7 @@
 // Sum returns the checksum for the downloaded copy of the given module,
 // if present in the download cache.
 func Sum(mod module.Version) string {
-	if PkgMod == "" {
+	if cfg.GOMODCACHE == "" {
 		// Do not use current directory.
 		return ""
 	}
diff --git a/libgo/go/cmd/go/internal/modfetch/proxy.go b/libgo/go/cmd/go/internal/modfetch/proxy.go
index dcea71a..1c35d0b 100644
--- a/libgo/go/cmd/go/internal/modfetch/proxy.go
+++ b/libgo/go/cmd/go/internal/modfetch/proxy.go
@@ -101,27 +101,51 @@
 
 var proxyOnce struct {
 	sync.Once
-	list []string
+	list []proxySpec
 	err  error
 }
 
-func proxyURLs() ([]string, error) {
+type proxySpec struct {
+	// url is the proxy URL or one of "off", "direct", "noproxy".
+	url string
+
+	// fallBackOnError is true if a request should be attempted on the next proxy
+	// in the list after any error from this proxy. If fallBackOnError is false,
+	// the request will only be attempted on the next proxy if the error is
+	// equivalent to os.ErrNotFound, which is true for 404 and 410 responses.
+	fallBackOnError bool
+}
+
+func proxyList() ([]proxySpec, error) {
 	proxyOnce.Do(func() {
 		if cfg.GONOPROXY != "" && cfg.GOPROXY != "direct" {
-			proxyOnce.list = append(proxyOnce.list, "noproxy")
+			proxyOnce.list = append(proxyOnce.list, proxySpec{url: "noproxy"})
 		}
-		for _, proxyURL := range strings.Split(cfg.GOPROXY, ",") {
-			proxyURL = strings.TrimSpace(proxyURL)
-			if proxyURL == "" {
+
+		goproxy := cfg.GOPROXY
+		for goproxy != "" {
+			var url string
+			fallBackOnError := false
+			if i := strings.IndexAny(goproxy, ",|"); i >= 0 {
+				url = goproxy[:i]
+				fallBackOnError = goproxy[i] == '|'
+				goproxy = goproxy[i+1:]
+			} else {
+				url = goproxy
+				goproxy = ""
+			}
+
+			url = strings.TrimSpace(url)
+			if url == "" {
 				continue
 			}
-			if proxyURL == "off" {
+			if url == "off" {
 				// "off" always fails hard, so can stop walking list.
-				proxyOnce.list = append(proxyOnce.list, "off")
+				proxyOnce.list = append(proxyOnce.list, proxySpec{url: "off"})
 				break
 			}
-			if proxyURL == "direct" {
-				proxyOnce.list = append(proxyOnce.list, "direct")
+			if url == "direct" {
+				proxyOnce.list = append(proxyOnce.list, proxySpec{url: "direct"})
 				// For now, "direct" is the end of the line. We may decide to add some
 				// sort of fallback behavior for them in the future, so ignore
 				// subsequent entries for forward-compatibility.
@@ -131,18 +155,29 @@
 			// Single-word tokens are reserved for built-in behaviors, and anything
 			// containing the string ":/" or matching an absolute file path must be a
 			// complete URL. For all other paths, implicitly add "https://".
-			if strings.ContainsAny(proxyURL, ".:/") && !strings.Contains(proxyURL, ":/") && !filepath.IsAbs(proxyURL) && !path.IsAbs(proxyURL) {
-				proxyURL = "https://" + proxyURL
+			if strings.ContainsAny(url, ".:/") && !strings.Contains(url, ":/") && !filepath.IsAbs(url) && !path.IsAbs(url) {
+				url = "https://" + url
 			}
 
 			// Check that newProxyRepo accepts the URL.
 			// It won't do anything with the path.
-			_, err := newProxyRepo(proxyURL, "golang.org/x/text")
-			if err != nil {
+			if _, err := newProxyRepo(url, "golang.org/x/text"); err != nil {
 				proxyOnce.err = err
 				return
 			}
-			proxyOnce.list = append(proxyOnce.list, proxyURL)
+
+			proxyOnce.list = append(proxyOnce.list, proxySpec{
+				url:             url,
+				fallBackOnError: fallBackOnError,
+			})
+		}
+
+		if len(proxyOnce.list) == 0 ||
+			len(proxyOnce.list) == 1 && proxyOnce.list[0].url == "noproxy" {
+			// There were no proxies, other than the implicit "noproxy" added when
+			// GONOPROXY is set. This can happen if GOPROXY is a non-empty string
+			// like "," or " ".
+			proxyOnce.err = fmt.Errorf("GOPROXY list is not the empty string, but contains no entries")
 		}
 	})
 
@@ -150,44 +185,60 @@
 }
 
 // TryProxies iterates f over each configured proxy (including "noproxy" and
-// "direct" if applicable) until f returns an error that is not
-// equivalent to os.ErrNotExist.
+// "direct" if applicable) until f returns no error or until f returns an
+// error that is not equivalent to os.ErrNotExist on a proxy configured
+// not to fall back on errors.
 //
 // TryProxies then returns that final error.
 //
 // If GOPROXY is set to "off", TryProxies invokes f once with the argument
 // "off".
 func TryProxies(f func(proxy string) error) error {
-	proxies, err := proxyURLs()
+	proxies, err := proxyList()
 	if err != nil {
 		return err
 	}
 	if len(proxies) == 0 {
-		return f("off")
+		panic("GOPROXY list is empty")
 	}
 
-	var lastAttemptErr error
+	// We try to report the most helpful error to the user. "direct" and "noproxy"
+	// errors are best, followed by proxy errors other than ErrNotExist, followed
+	// by ErrNotExist.
+	//
+	// Note that errProxyOff, errNoproxy, and errUseProxy are equivalent to
+	// ErrNotExist. errUseProxy should only be returned if "noproxy" is the only
+	// proxy. errNoproxy should never be returned, since there should always be a
+	// more useful error from "noproxy" first.
+	const (
+		notExistRank = iota
+		proxyRank
+		directRank
+	)
+	var bestErr error
+	bestErrRank := notExistRank
 	for _, proxy := range proxies {
-		err = f(proxy)
-		if !errors.Is(err, os.ErrNotExist) {
-			lastAttemptErr = err
+		err := f(proxy.url)
+		if err == nil {
+			return nil
+		}
+		isNotExistErr := errors.Is(err, os.ErrNotExist)
+
+		if proxy.url == "direct" || (proxy.url == "noproxy" && err != errUseProxy) {
+			bestErr = err
+			bestErrRank = directRank
+		} else if bestErrRank <= proxyRank && !isNotExistErr {
+			bestErr = err
+			bestErrRank = proxyRank
+		} else if bestErrRank == notExistRank {
+			bestErr = err
+		}
+
+		if !proxy.fallBackOnError && !isNotExistErr {
 			break
 		}
-
-		// The error indicates that the module does not exist.
-		// In general we prefer to report the last such error,
-		// because it indicates the error that occurs after all other
-		// options have been exhausted.
-		//
-		// However, for modules in the NOPROXY list, the most useful error occurs
-		// first (with proxy set to "noproxy"), and the subsequent errors are all
-		// errNoProxy (which is not particularly helpful). Do not overwrite a more
-		// useful error with errNoproxy.
-		if lastAttemptErr == nil || !errors.Is(err, errNoproxy) {
-			lastAttemptErr = err
-		}
 	}
-	return lastAttemptErr
+	return bestErr
 }
 
 type proxyRepo struct {
@@ -205,12 +256,12 @@
 		// ok
 	case "file":
 		if *base != (url.URL{Scheme: base.Scheme, Path: base.Path, RawPath: base.RawPath}) {
-			return nil, fmt.Errorf("invalid file:// proxy URL with non-path elements: %s", web.Redacted(base))
+			return nil, fmt.Errorf("invalid file:// proxy URL with non-path elements: %s", base.Redacted())
 		}
 	case "":
-		return nil, fmt.Errorf("invalid proxy URL missing scheme: %s", web.Redacted(base))
+		return nil, fmt.Errorf("invalid proxy URL missing scheme: %s", base.Redacted())
 	default:
-		return nil, fmt.Errorf("invalid proxy URL scheme (must be https, http, file): %s", web.Redacted(base))
+		return nil, fmt.Errorf("invalid proxy URL scheme (must be https, http, file): %s", base.Redacted())
 	}
 
 	enc, err := module.EscapePath(path)
diff --git a/libgo/go/cmd/go/internal/modfetch/pseudo.go b/libgo/go/cmd/go/internal/modfetch/pseudo.go
index 57dee11..20c0b06 100644
--- a/libgo/go/cmd/go/internal/modfetch/pseudo.go
+++ b/libgo/go/cmd/go/internal/modfetch/pseudo.go
@@ -48,6 +48,8 @@
 
 var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`)
 
+const pseudoVersionTimestampFormat = "20060102150405"
+
 // PseudoVersion returns a pseudo-version for the given major version ("v1")
 // preexisting older tagged version ("" or "v1.2.3" or "v1.2.3-pre"), revision time,
 // and revision identifier (usually a 12-byte commit hash prefix).
@@ -55,7 +57,7 @@
 	if major == "" {
 		major = "v0"
 	}
-	segment := fmt.Sprintf("%s-%s", t.UTC().Format("20060102150405"), rev)
+	segment := fmt.Sprintf("%s-%s", t.UTC().Format(pseudoVersionTimestampFormat), rev)
 	build := semver.Build(older)
 	older = semver.Canonical(older)
 	if older == "" {
diff --git a/libgo/go/cmd/go/internal/modfetch/sumdb.go b/libgo/go/cmd/go/internal/modfetch/sumdb.go
index 1ed71df..7973f47 100644
--- a/libgo/go/cmd/go/internal/modfetch/sumdb.go
+++ b/libgo/go/cmd/go/internal/modfetch/sumdb.go
@@ -26,6 +26,7 @@
 	"cmd/go/internal/lockedfile"
 	"cmd/go/internal/str"
 	"cmd/go/internal/web"
+
 	"golang.org/x/mod/module"
 	"golang.org/x/mod/sumdb"
 	"golang.org/x/mod/sumdb/note"
@@ -130,7 +131,7 @@
 	targ := web.Join(c.base, path)
 	data, err := web.GetBytes(targ)
 	if false {
-		fmt.Fprintf(os.Stderr, "%.3fs %s\n", time.Since(start).Seconds(), web.Redacted(targ))
+		fmt.Fprintf(os.Stderr, "%.3fs %s\n", time.Since(start).Seconds(), targ.Redacted())
 	}
 	return data, err
 }
@@ -146,49 +147,50 @@
 	}
 
 	// Try proxies in turn until we find out how to connect to this database.
-	urls, err := proxyURLs()
-	if err != nil {
-		c.baseErr = err
-		return
-	}
-	for _, proxyURL := range urls {
-		if proxyURL == "noproxy" {
-			continue
-		}
-		if proxyURL == "direct" || proxyURL == "off" {
-			break
-		}
-		proxy, err := url.Parse(proxyURL)
-		if err != nil {
-			c.baseErr = err
-			return
-		}
-		// Quoting https://golang.org/design/25530-sumdb#proxying-a-checksum-database:
-		//
-		// Before accessing any checksum database URL using a proxy,
-		// the proxy client should first fetch <proxyURL>/sumdb/<sumdb-name>/supported.
-		// If that request returns a successful (HTTP 200) response, then the proxy supports
-		// proxying checksum database requests. In that case, the client should use
-		// the proxied access method only, never falling back to a direct connection to the database.
-		// If the /sumdb/<sumdb-name>/supported check fails with a “not found” (HTTP 404)
-		// or “gone” (HTTP 410) response, the proxy is unwilling to proxy the checksum database,
-		// and the client should connect directly to the database.
-		// Any other response is treated as the database being unavailable.
-		_, err = web.GetBytes(web.Join(proxy, "sumdb/"+c.name+"/supported"))
-		if err == nil {
+	//
+	// Before accessing any checksum database URL using a proxy, the proxy
+	// client should first fetch <proxyURL>/sumdb/<sumdb-name>/supported.
+	//
+	// If that request returns a successful (HTTP 200) response, then the proxy
+	// supports proxying checksum database requests. In that case, the client
+	// should use the proxied access method only, never falling back to a direct
+	// connection to the database.
+	//
+	// If the /sumdb/<sumdb-name>/supported check fails with a “not found” (HTTP
+	// 404) or “gone” (HTTP 410) response, or if the proxy is configured to fall
+	// back on errors, the client will try the next proxy. If there are no
+	// proxies left or if the proxy is "direct" or "off", the client should
+	// connect directly to that database.
+	//
+	// Any other response is treated as the database being unavailable.
+	//
+	// See https://golang.org/design/25530-sumdb#proxying-a-checksum-database.
+	err := TryProxies(func(proxy string) error {
+		switch proxy {
+		case "noproxy":
+			return errUseProxy
+		case "direct", "off":
+			return errProxyOff
+		default:
+			proxyURL, err := url.Parse(proxy)
+			if err != nil {
+				return err
+			}
+			if _, err := web.GetBytes(web.Join(proxyURL, "sumdb/"+c.name+"/supported")); err != nil {
+				return err
+			}
 			// Success! This proxy will help us.
-			c.base = web.Join(proxy, "sumdb/"+c.name)
-			return
+			c.base = web.Join(proxyURL, "sumdb/"+c.name)
+			return nil
 		}
-		// If the proxy serves a non-404/410, give up.
-		if !errors.Is(err, os.ErrNotExist) {
-			c.baseErr = err
-			return
-		}
+	})
+	if errors.Is(err, os.ErrNotExist) {
+		// No proxies, or all proxies failed (with 404, 410, or were were allowed
+		// to fall back), or we reached an explicit "direct" or "off".
+		c.base = c.direct
+	} else if err != nil {
+		c.baseErr = err
 	}
-
-	// No proxies, or all proxies said 404, or we reached an explicit "direct".
-	c.base = c.direct
 }
 
 // ReadConfig reads the key from c.key
@@ -198,8 +200,10 @@
 		return []byte(c.key), nil
 	}
 
-	// GOPATH/pkg is PkgMod/..
-	targ := filepath.Join(PkgMod, "../sumdb/"+file)
+	if cfg.SumdbDir == "" {
+		return nil, errors.New("could not locate sumdb file: missing $GOPATH")
+	}
+	targ := filepath.Join(cfg.SumdbDir, file)
 	data, err = lockedfile.Read(targ)
 	if errors.Is(err, os.ErrNotExist) {
 		// Treat non-existent as empty, to bootstrap the "latest" file
@@ -215,7 +219,10 @@
 		// Should not happen.
 		return fmt.Errorf("cannot write key")
 	}
-	targ := filepath.Join(PkgMod, "../sumdb/"+file)
+	if cfg.SumdbDir == "" {
+		return errors.New("could not locate sumdb file: missing $GOPATH")
+	}
+	targ := filepath.Join(cfg.SumdbDir, file)
 	os.MkdirAll(filepath.Dir(targ), 0777)
 	f, err := lockedfile.Edit(targ)
 	if err != nil {
@@ -245,7 +252,7 @@
 // GOPATH/pkg/mod/cache/download/sumdb,
 // which will be deleted by "go clean -modcache".
 func (*dbClient) ReadCache(file string) ([]byte, error) {
-	targ := filepath.Join(PkgMod, "cache/download/sumdb", file)
+	targ := filepath.Join(cfg.GOMODCACHE, "cache/download/sumdb", file)
 	data, err := lockedfile.Read(targ)
 	// lockedfile.Write does not atomically create the file with contents.
 	// There is a moment between file creation and locking the file for writing,
@@ -259,7 +266,7 @@
 
 // WriteCache updates cached lookups or tiles.
 func (*dbClient) WriteCache(file string, data []byte) {
-	targ := filepath.Join(PkgMod, "cache/download/sumdb", file)
+	targ := filepath.Join(cfg.GOMODCACHE, "cache/download/sumdb", file)
 	os.MkdirAll(filepath.Dir(targ), 0777)
 	lockedfile.Write(targ, bytes.NewReader(data), 0666)
 }
diff --git a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv
index 6eb8d7f..0906975 100644
--- a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv
+++ b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv
@@ -40,7 +40,6 @@
 gitee.com/nggs/util,v0.0.0-20190830024003-3e49d2efc84b,h1:6KQpPEs326uPrICQy9x/PxmR8U0v/XsFzpt0k1nFKcY=,a062c99c2b560a36168fe51eab8f17f4fadf5d534238881628e83d8d61e51c2a
 github.com/1and1/oneandone-cloudserver-sdk-go,v1.0.1,h1:RMTyvS5bjvSWiUcfqfr/E2pxHEMrALvU+E12n6biymg=,7f068808fc0857d7de8c8f829cc380dce1c6611a3fc819daf4421e9bcb75a07c
 github.com/99designs/gqlgen,v0.10.1,h1:1BgB6XKGTHq7uH4G1/PYyKe2Kz7/vw3AlvMZlD3TEEY=,04b9e7d8a3df6543cd870325b1140ce9ac3f4bbfd8c90ebecec4f908dd420d08
-github.com/AlexStocks/log4go,v1.0.5,h1:45boeHy0qh0NFBaEhrFT/pUKzQUGf7q2Ux1iQDr/f6o=,59371c2108f62aa9a2233ca8f7de57868ad2c64313b2d68434e0ed6a1748ce2c
 github.com/AndreasBriese/bbloom,v0.0.0-20190306092124-e2d15f34fcf9,h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4=,6d7c1af06f8597fde1e86166f26416057392f1b0bdb84f2af555aa461282dd18
 github.com/AsynkronIT/goconsole,v0.0.0-20160504192649-bfa12eebf716,h1:Pk/Kzi5O0T4QxfqvbaUsh8UklbJ9BklZ/ClZBptX5WU=,5a2507b89bb4436881718d785a0ef383652aa99782508b7444cf20255082dab9
 github.com/Azure/azure-amqp-common-go,v1.1.4,h1:DmPXxmLZwi/71CgRTZIKR6yiKEW3eC42S4gSBhfG7y0=,4b800793ff4fefa86a427c445e3a4671b8d1dcd87a44075f6309cace6b0e01e2
@@ -243,7 +242,6 @@
 github.com/beevik/etree,v1.1.0,h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=,614a33736f8b9262a809f101df5bf71f47777879b1191165b6247d6b67c7468c
 github.com/beevik/guid,v0.0.0-20170504223318-d0ea8faecee0,h1:oLd/YLOTOgA4D4aAUhIE8vhl/LAP1ZJrj0mDQpl7GB8=,5add94fcade6c7afa236112c8da300d47ec499ad1789a5e805c8198062dd0749
 github.com/beevik/ntp,v0.2.0,h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=,42e14f30c23ba2f5ddaff76101016d87f0f0a0f1d96d3d20e42fd02842091c76
-github.com/belogik/goes,v0.0.0-20151229125003-e54d722c3aff,h1:/kO0p2RTGLB8R5gub7ps0GmYpB2O8LXEoPq8tzFDCUI=,f926f1040febe5318efa145541a6fc7898d32514bc13899e812185f05710c5db
 github.com/beorn7/perks,v1.0.1,h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=,25bd9e2d94aca770e6dbc1f53725f84f6af4432f631d35dd2c46f96ef0512f1a
 github.com/bep/debounce,v1.2.0,h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo=,ddc0a77e4819b6b826d69fdf1a5a153f3f867a31e030cfe28296355b670adf21
 github.com/bep/gitmap,v1.1.1,h1:Nf8ySnC3I7/xPjuWeCwzukUFv185iTUQ6nOvLy9gCJA=,364163e67741ae331d164fd881964160f19fdbdfe094e0e762314cc37aac646a
@@ -1461,7 +1459,6 @@
 github.com/opencontainers/runtime-spec,v1.0.1,h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ=,1958458b00ce912425f5c7d2ee836431b296a3f9320d565512d8c96b107fffbf
 github.com/opencontainers/runtime-tools,v0.9.0,h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU=,53c720dbb7452cfb2fd3945e37c26b5a0140cb1012d35a2b72a5e035f28a32c4
 github.com/opencontainers/selinux,v1.3.0,h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqGe5TgR0g=,88286825b32cd46a0469e578f378a185032da2d5b03893623861ef3af59359d8
-github.com/openshift/api,v3.9.0+incompatible,h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs=,fc087ac9809ce58bdd15614e04c13f8ecc4a17e71addbe6eb6b777c377b01243
 github.com/openshift/client-go,v3.9.0+incompatible,h1:13k3Ok0B7TA2hA3bQW2aFqn6y04JaJWdk7ITTyg+Ek0=,661b7f28b4905f1936dd58e373374513d54663ec85aecafede1c7d9c260e9369
 github.com/openshift/library-go,v0.0.0-20191101161407-e7c97b468b83,h1:wwR+laNaFKVGiizoIDL/cAKIZVoKXJ9jbjUoUlq2p5I=,c74f8134013f978ef154d6accf9b4b0c5126941f2d45e6eb223db7098f7ab2a4
 github.com/opentracing-contrib/go-observer,v0.0.0-20170622124052-a52f23424492,h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU=,50023eee1ef04412410f43d8b5dcf3ef481c0fc39067add27799654705fa84b2
@@ -1882,7 +1879,6 @@
 github.com/zquestz/grab,v0.0.0-20190224022517-abcee96e61b1,h1:1qKTeMTSIEvRIjvVYzgcRp0xVp0eoiRTTiHSncb5gD8=,4decd67f1252df4ee34968cb0cb4e7dc6010302b24ce8edd418f1c2520f1c351
 gitlab.com/NebulousLabs/errors,v0.0.0-20171229012116-7ead97ef90b8,h1:gZfMjx7Jr6N8b7iJO4eUjDsn6xJqoyXg8D+ogdoAfKY=,b355474f1a2ef2722ae450ef6df7209d223188ae413706be122b472fcc053c48
 gitlab.com/NebulousLabs/fastrand,v0.0.0-20181126182046-603482d69e40,h1:dizWJqTWjwyD8KGcMOwgrkqu1JIkofYgKkmDeNE7oAs=,a56acdda993c7a4795028fe38844d54de9b1877d22e8ae09f205e488ce2284bc
-gitlab.com/yumeko/MumbleEmu,v0.0.0-20170923112213-54c9892f02e9,h1:QSaGLacCEAlWXhL/xGZyS3+2aDVvBZe5jcmrDWwXhqs=,51cc295a04dc3b9c39b341f21b95fc42765e3bb61fe30ec2a59fe867c1b5e5ed
 go.bug.st/serial.v1,v0.0.0-20180827123349-5f7892a7bb45,h1:mACY1anK6HNCZtm/DK2Rf2ZPHggVqeB0+7rY9Gl6wyI=,f0ea4cd4c51228f1a3cf14c6b92888169944f267e1ee778909512a4c8ac4762f
 go.cryptoscope.co/luigi,v0.3.4,h1:eDrtCoUL5Vl2Atr5ty2dq0uFbzFCc6Pz1HEqU1e7I1I=,949612e92dcb2fc919e506740f36d0cfe0797c1f85579a98763aad0135a4580a
 go.dedis.ch/fixbuf,v1.0.3,h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=,dfa737543a5873b14cdfd0eec675c63044b16d3dbe481b2289c758ae4186ae95
@@ -2085,7 +2081,6 @@
 leb.io/aeshash,v0.0.0-20190627052759-9e6b40329b3b,h1:MG17Tc0pA3XmFTsPwklMMEfcos3pTFnVYM4A0YfVSbU=,a78b48ac18e98ea68dacce16cd94c9074688a0b125f824f047313a33b264ea88
 leb.io/hashland,v0.0.0-20171003003232-07375b562dea,h1:s9IkzZTqYqw77voO6taUZHc0C1B096h4T/kQtujGApE=,0698177f24cbde0a7b45495e7fe976fe7623f2b9205995b7d91fd2e7b0f0e243
 leb.io/hrff,v0.0.0-20170927164517-757f8bd43e20,h1:9CHS8LIq9MDwUsAaCHUsbUq7zb5lSjLQYWlJ/AbMZKg=,538008712599401a903a7982714c0a9ae745221042d3dfb1437bc508d8fb9e96
-llvm.org/llvm,v0.0.0-20191022153947-000000375505,h1:cncItmsQ0kcXFrnkQZv2TGle2ELPCEDi3Q36Kf2T3yg=,3f48da9846fc0f69ccc447ead4480f8c7f2b44b0c24b98a793d36d8cb2a572c0
 modernc.org/cc,v1.0.0,h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ=,24711e9b28b0d79dd32438eeb7debd86b850350f5f7749b7af640422ecf6b93b
 modernc.org/golex,v1.0.0,h1:wWpDlbK8ejRfSyi0frMyhilD3JBvtcx2AdGDnU+JtsE=,335133038991d7feaba5349ac2385db7b49601bba0904abf680803ee2d3c99df
 modernc.org/mathutil,v1.0.0,h1:93vKjrJopTPrtTNpZ8XIovER7iCIH1QU7wNbOQXC60I=,766ad95195543fe1ac217ce9f54e1fb43119c25db2b89013b9ef5477ad2dd9d1
diff --git a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go
index 331d634..eac9b32 100644
--- a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go
+++ b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go
@@ -126,7 +126,7 @@
 					test.m.Path = "" // mark for deletion
 					needUpdate = true
 				} else {
-					t.Errorf("%s: could not download mdoule: %s", test.m, err)
+					t.Errorf("%s: could not download module: %s", test.m, err)
 				}
 				return
 			}
diff --git a/libgo/go/cmd/go/internal/modget/get.go b/libgo/go/cmd/go/internal/modget/get.go
index 2a0f634..4c69824 100644
--- a/libgo/go/cmd/go/internal/modget/get.go
+++ b/libgo/go/cmd/go/internal/modget/get.go
@@ -114,7 +114,10 @@
 this automatically as well.
 
 The -insecure flag permits fetching from repositories and resolving
-custom domains using insecure schemes such as HTTP. Use with caution.
+custom domains using insecure schemes such as HTTP. Use with caution. The
+GOINSECURE environment variable is usually a better alternative, since it
+provides control over which modules may be retrieved using an insecure scheme.
+See 'go help environment' for details.
 
 The second step is to download (if needed), build, and install
 the named packages.
@@ -307,6 +310,20 @@
 			continue
 		}
 
+		// Guard against 'go get x.go', a common mistake.
+		// Note that package and module paths may end with '.go', so only print an error
+		// if the argument has no version and either has no slash or refers to an existing file.
+		if strings.HasSuffix(arg, ".go") && vers == "" {
+			if !strings.Contains(arg, "/") {
+				base.Errorf("go get %s: arguments must be package or module paths", arg)
+				continue
+			}
+			if fi, err := os.Stat(arg); err == nil && !fi.IsDir() {
+				base.Errorf("go get: %s exists as a file, but 'go get' requires package arguments", arg)
+				continue
+			}
+		}
+
 		// If no version suffix is specified, assume @upgrade.
 		// If -u=patch was specified, assume @patch instead.
 		if vers == "" {
@@ -326,15 +343,22 @@
 		// patterns like golang.org/x/tools/..., which can't be expanded
 		// during package loading until they're in the build list.
 		switch {
-		case search.IsRelativePath(path):
-			// Relative paths like ../../foo or ../../foo... are restricted to
-			// matching packages in the main module. If the path is explicit and
-			// contains no wildcards (...), check that it is a package in
-			// the main module. If the path contains wildcards but matches no
-			// packages, we'll warn after package loading.
+		case filepath.IsAbs(path) || search.IsRelativePath(path):
+			// Absolute paths like C:\foo and relative paths like ../foo...
+			// are restricted to matching packages in the main module. If the path
+			// is explicit and contains no wildcards (...), check that it is a
+			// package in the main module. If the path contains wildcards but
+			// matches no packages, we'll warn after package loading.
 			if !strings.Contains(path, "...") {
-				pkgPath := modload.DirImportPath(filepath.FromSlash(path))
-				if pkgs := modload.TargetPackages(pkgPath); len(pkgs) == 0 {
+				m := search.NewMatch(path)
+				if pkgPath := modload.DirImportPath(path); pkgPath != "." {
+					m = modload.TargetPackages(pkgPath)
+				}
+				if len(m.Pkgs) == 0 {
+					for _, err := range m.Errs {
+						base.Errorf("go get %s: %v", arg, err)
+					}
+
 					abs, err := filepath.Abs(path)
 					if err != nil {
 						abs = path
@@ -374,7 +398,7 @@
 		default:
 			// The argument is a package or module path.
 			if modload.HasModRoot() {
-				if pkgs := modload.TargetPackages(path); len(pkgs) != 0 {
+				if m := modload.TargetPackages(path); len(m.Pkgs) != 0 {
 					// The path is in the main module. Nothing to query.
 					if vers != "upgrade" && vers != "patch" {
 						base.Errorf("go get %s: can't request explicit version of path in main module", arg)
@@ -520,8 +544,12 @@
 					// If the pattern did not match any packages, look up a new module.
 					// If the pattern doesn't match anything on the last iteration,
 					// we'll print a warning after the outer loop.
-					if !search.IsRelativePath(arg.path) && !match.Literal && arg.path != "all" {
+					if !match.IsLocal() && !match.IsLiteral() && arg.path != "all" {
 						addQuery(&query{querySpec: querySpec{path: arg.path, vers: arg.vers}, arg: arg.raw})
+					} else {
+						for _, err := range match.Errs {
+							base.Errorf("go get: %v", err)
+						}
 					}
 					continue
 				}
diff --git a/libgo/go/cmd/go/internal/modload/build.go b/libgo/go/cmd/go/internal/modload/build.go
index 2a69d59..e7e7d56 100644
--- a/libgo/go/cmd/go/internal/modload/build.go
+++ b/libgo/go/cmd/go/internal/modload/build.go
@@ -205,6 +205,7 @@
 	if isStandardImportPath(path) || !Enabled() {
 		return ""
 	}
+
 	target := mustFindModule(path, path)
 	mdeps := make(map[module.Version]bool)
 	for _, dep := range deps {
@@ -221,26 +222,25 @@
 
 	var buf bytes.Buffer
 	fmt.Fprintf(&buf, "path\t%s\n", path)
-	tv := target.Version
-	if tv == "" {
-		tv = "(devel)"
-	}
-	fmt.Fprintf(&buf, "mod\t%s\t%s\t%s\n", target.Path, tv, modfetch.Sum(target))
-	for _, mod := range mods {
-		mv := mod.Version
+
+	writeEntry := func(token string, m module.Version) {
+		mv := m.Version
 		if mv == "" {
 			mv = "(devel)"
 		}
-		r := Replacement(mod)
-		h := ""
-		if r.Path == "" {
-			h = "\t" + modfetch.Sum(mod)
-		}
-		fmt.Fprintf(&buf, "dep\t%s\t%s%s\n", mod.Path, mv, h)
-		if r.Path != "" {
-			fmt.Fprintf(&buf, "=>\t%s\t%s\t%s\n", r.Path, r.Version, modfetch.Sum(r))
+		fmt.Fprintf(&buf, "%s\t%s\t%s", token, m.Path, mv)
+		if r := Replacement(m); r.Path == "" {
+			fmt.Fprintf(&buf, "\t%s\n", modfetch.Sum(m))
+		} else {
+			fmt.Fprintf(&buf, "\n=>\t%s\t%s\t%s\n", r.Path, r.Version, modfetch.Sum(r))
 		}
 	}
+
+	writeEntry("mod", target)
+	for _, mod := range mods {
+		writeEntry("dep", mod)
+	}
+
 	return buf.String()
 }
 
diff --git a/libgo/go/cmd/go/internal/modload/help.go b/libgo/go/cmd/go/internal/modload/help.go
index bd19bb4..d80206b 100644
--- a/libgo/go/cmd/go/internal/modload/help.go
+++ b/libgo/go/cmd/go/internal/modload/help.go
@@ -363,15 +363,15 @@
 Go module mirror run by Google and fall back to a direct connection
 if the proxy reports that it does not have the module (HTTP error 404 or 410).
 See https://proxy.golang.org/privacy for the service's privacy policy.
-If GOPROXY is set to the string "direct", downloads use a direct connection
-to source control servers. Setting GOPROXY to "off" disallows downloading
-modules from any source. Otherwise, GOPROXY is expected to be a comma-separated
-list of the URLs of module proxies, in which case the go command will fetch
-modules from those proxies. For each request, the go command tries each proxy
-in sequence, only moving to the next if the current proxy returns a 404 or 410
-HTTP response. The string "direct" may appear in the proxy list,
-to cause a direct connection to be attempted at that point in the search.
-Any proxies listed after "direct" are never consulted.
+
+If GOPROXY is set to the string "direct", downloads use a direct connection to
+source control servers. Setting GOPROXY to "off" disallows downloading modules
+from any source. Otherwise, GOPROXY is expected to be list of module proxy URLs
+separated by either comma (,) or pipe (|) characters, which control error
+fallback behavior. For each request, the go command tries each proxy in
+sequence. If there is an error, the go command will try the next proxy in the
+list if the error is a 404 or 410 HTTP response or if the current proxy is
+followed by a pipe character, indicating it is safe to fall back on any error.
 
 The GOPRIVATE and GONOPROXY environment variables allow bypassing
 the proxy for selected modules. See 'go help module-private' for details.
diff --git a/libgo/go/cmd/go/internal/modload/import.go b/libgo/go/cmd/go/internal/modload/import.go
index d7fca8f..4d2bc80 100644
--- a/libgo/go/cmd/go/internal/modload/import.go
+++ b/libgo/go/cmd/go/internal/modload/import.go
@@ -62,11 +62,15 @@
 // modules in the build list, or found in both the main module and its vendor
 // directory.
 type AmbiguousImportError struct {
-	ImportPath string
+	importPath string
 	Dirs       []string
 	Modules    []module.Version // Either empty or 1:1 with Dirs.
 }
 
+func (e *AmbiguousImportError) ImportPath() string {
+	return e.importPath
+}
+
 func (e *AmbiguousImportError) Error() string {
 	locType := "modules"
 	if len(e.Modules) == 0 {
@@ -74,7 +78,7 @@
 	}
 
 	var buf strings.Builder
-	fmt.Fprintf(&buf, "ambiguous import: found package %s in multiple %s:", e.ImportPath, locType)
+	fmt.Fprintf(&buf, "ambiguous import: found package %s in multiple %s:", e.importPath, locType)
 
 	for i, dir := range e.Dirs {
 		buf.WriteString("\n\t")
@@ -93,6 +97,8 @@
 	return buf.String()
 }
 
+var _ load.ImportPathError = &AmbiguousImportError{}
+
 // Import finds the module and directory in the build list
 // containing the package with the given import path.
 // The answer must be unique: Import returns an error
@@ -120,7 +126,9 @@
 	pathIsStd := search.IsStandardImportPath(path)
 	if pathIsStd && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) {
 		if targetInGorootSrc {
-			if dir, ok := dirInModule(path, targetPrefix, ModRoot(), true); ok {
+			if dir, ok, err := dirInModule(path, targetPrefix, ModRoot(), true); err != nil {
+				return module.Version{}, dir, err
+			} else if ok {
 				return Target, dir, nil
 			}
 		}
@@ -131,10 +139,10 @@
 	// -mod=vendor is special.
 	// Everything must be in the main module or the main module's vendor directory.
 	if cfg.BuildMod == "vendor" {
-		mainDir, mainOK := dirInModule(path, targetPrefix, ModRoot(), true)
-		vendorDir, vendorOK := dirInModule(path, "", filepath.Join(ModRoot(), "vendor"), false)
+		mainDir, mainOK, mainErr := dirInModule(path, targetPrefix, ModRoot(), true)
+		vendorDir, vendorOK, _ := dirInModule(path, "", filepath.Join(ModRoot(), "vendor"), false)
 		if mainOK && vendorOK {
-			return module.Version{}, "", &AmbiguousImportError{ImportPath: path, Dirs: []string{mainDir, vendorDir}}
+			return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: []string{mainDir, vendorDir}}
 		}
 		// Prefer to return main directory if there is one,
 		// Note that we're not checking that the package exists.
@@ -142,6 +150,9 @@
 		if !vendorOK && mainDir != "" {
 			return Target, mainDir, nil
 		}
+		if mainErr != nil {
+			return module.Version{}, "", mainErr
+		}
 		readVendorList()
 		return vendorPkgModule[path], vendorDir, nil
 	}
@@ -164,8 +175,9 @@
 			// not ambiguous.
 			return module.Version{}, "", err
 		}
-		dir, ok := dirInModule(path, m.Path, root, isLocal)
-		if ok {
+		if dir, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil {
+			return module.Version{}, "", err
+		} else if ok {
 			mods = append(mods, m)
 			dirs = append(dirs, dir)
 		}
@@ -174,7 +186,7 @@
 		return mods[0], dirs[0], nil
 	}
 	if len(mods) > 0 {
-		return module.Version{}, "", &AmbiguousImportError{ImportPath: path, Dirs: dirs, Modules: mods}
+		return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: dirs, Modules: mods}
 	}
 
 	// Look up module containing the package, for addition to the build list.
@@ -241,8 +253,9 @@
 				// Report fetch error as above.
 				return module.Version{}, "", err
 			}
-			_, ok := dirInModule(path, m.Path, root, isLocal)
-			if ok {
+			if _, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil {
+				return m, "", err
+			} else if ok {
 				return m, "", &ImportMissingError{Path: path, Module: m}
 			}
 		}
@@ -313,19 +326,29 @@
 		len(path) > len(mpath) && path[len(mpath)] == '/' && path[:len(mpath)] == mpath
 }
 
-var haveGoModCache, haveGoFilesCache par.Cache
+var (
+	haveGoModCache   par.Cache // dir → bool
+	haveGoFilesCache par.Cache // dir → goFilesEntry
+)
+
+type goFilesEntry struct {
+	haveGoFiles bool
+	err         error
+}
 
 // dirInModule locates the directory that would hold the package named by the given path,
 // if it were in the module with module path mpath and root mdir.
 // If path is syntactically not within mpath,
 // or if mdir is a local file tree (isLocal == true) and the directory
 // that would hold path is in a sub-module (covered by a go.mod below mdir),
-// dirInModule returns "", false.
+// dirInModule returns "", false, nil.
 //
 // Otherwise, dirInModule returns the name of the directory where
 // Go source files would be expected, along with a boolean indicating
 // whether there are in fact Go source files in that directory.
-func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFiles bool) {
+// A non-nil error indicates that the existence of the directory and/or
+// source files could not be determined, for example due to a permission error.
+func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFiles bool, err error) {
 	// Determine where to expect the package.
 	if path == mpath {
 		dir = mdir
@@ -334,7 +357,7 @@
 	} else if len(path) > len(mpath) && path[len(mpath)] == '/' && path[:len(mpath)] == mpath {
 		dir = filepath.Join(mdir, path[len(mpath)+1:])
 	} else {
-		return "", false
+		return "", false, nil
 	}
 
 	// Check that there aren't other modules in the way.
@@ -351,7 +374,7 @@
 			}).(bool)
 
 			if haveGoMod {
-				return "", false
+				return "", false, nil
 			}
 			parent := filepath.Dir(d)
 			if parent == d {
@@ -368,23 +391,58 @@
 	// Are there Go source files in the directory?
 	// We don't care about build tags, not even "+build ignore".
 	// We're just looking for a plausible directory.
-	haveGoFiles = haveGoFilesCache.Do(dir, func() interface{} {
-		f, err := os.Open(dir)
-		if err != nil {
-			return false
+	res := haveGoFilesCache.Do(dir, func() interface{} {
+		ok, err := isDirWithGoFiles(dir)
+		return goFilesEntry{haveGoFiles: ok, err: err}
+	}).(goFilesEntry)
+
+	return dir, res.haveGoFiles, res.err
+}
+
+func isDirWithGoFiles(dir string) (bool, error) {
+	f, err := os.Open(dir)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return false, nil
 		}
-		defer f.Close()
-		names, _ := f.Readdirnames(-1)
-		for _, name := range names {
-			if strings.HasSuffix(name, ".go") {
-				info, err := os.Stat(filepath.Join(dir, name))
-				if err == nil && info.Mode().IsRegular() {
-					return true
+		return false, err
+	}
+	defer f.Close()
+
+	names, firstErr := f.Readdirnames(-1)
+	if firstErr != nil {
+		if fi, err := f.Stat(); err == nil && !fi.IsDir() {
+			return false, nil
+		}
+
+		// Rewrite the error from ReadDirNames to include the path if not present.
+		// See https://golang.org/issue/38923.
+		var pe *os.PathError
+		if !errors.As(firstErr, &pe) {
+			firstErr = &os.PathError{Op: "readdir", Path: dir, Err: firstErr}
+		}
+	}
+
+	for _, name := range names {
+		if strings.HasSuffix(name, ".go") {
+			info, err := os.Stat(filepath.Join(dir, name))
+			if err == nil && info.Mode().IsRegular() {
+				// If any .go source file exists, the package exists regardless of
+				// errors for other source files. Leave further error reporting for
+				// later.
+				return true, nil
+			}
+			if firstErr == nil {
+				if os.IsNotExist(err) {
+					// If the file was concurrently deleted, or was a broken symlink,
+					// convert the error to an opaque error instead of one matching
+					// os.IsNotExist.
+					err = errors.New(err.Error())
 				}
+				firstErr = err
 			}
 		}
-		return false
-	}).(bool)
+	}
 
-	return dir, haveGoFiles
+	return false, firstErr
 }
diff --git a/libgo/go/cmd/go/internal/modload/init.go b/libgo/go/cmd/go/internal/modload/init.go
index 61cbdf2..664a2a1 100644
--- a/libgo/go/cmd/go/internal/modload/init.go
+++ b/libgo/go/cmd/go/internal/modload/init.go
@@ -26,7 +26,6 @@
 	"cmd/go/internal/lockedfile"
 	"cmd/go/internal/modconv"
 	"cmd/go/internal/modfetch"
-	"cmd/go/internal/modfetch/codehost"
 	"cmd/go/internal/mvs"
 	"cmd/go/internal/search"
 
@@ -59,27 +58,6 @@
 	allowMissingModuleImports bool
 )
 
-var modFile *modfile.File
-
-// A modFileIndex is an index of data corresponding to a modFile
-// at a specific point in time.
-type modFileIndex struct {
-	data         []byte
-	dataNeedsFix bool // true if fixVersion applied a change while parsing data
-	module       module.Version
-	goVersion    string
-	require      map[module.Version]requireMeta
-	replace      map[module.Version]module.Version
-	exclude      map[module.Version]bool
-}
-
-// index is the index of the go.mod file as of when it was last read or written.
-var index *modFileIndex
-
-type requireMeta struct {
-	indirect bool
-}
-
 // ModFile returns the parsed go.mod file.
 //
 // Note that after calling ImportPaths or LoadBuildList,
@@ -199,17 +177,6 @@
 		base.Fatalf("$GOPATH/go.mod exists but should not")
 	}
 
-	oldSrcMod := filepath.Join(list[0], "src/mod")
-	pkgMod := filepath.Join(list[0], "pkg/mod")
-	infoOld, errOld := os.Stat(oldSrcMod)
-	_, errMod := os.Stat(pkgMod)
-	if errOld == nil && infoOld.IsDir() && errMod != nil && os.IsNotExist(errMod) {
-		os.Rename(oldSrcMod, pkgMod)
-	}
-
-	modfetch.PkgMod = pkgMod
-	codehost.WorkRoot = filepath.Join(pkgMod, "cache/vcs")
-
 	cfg.ModulesEnabled = true
 	load.ModBinDir = BinDir
 	load.ModLookup = Lookup
@@ -246,13 +213,6 @@
 
 func init() {
 	load.ModInit = Init
-
-	// Set modfetch.PkgMod and codehost.WorkRoot unconditionally,
-	// so that go clean -modcache and go mod download can run even without modules enabled.
-	if list := filepath.SplitList(cfg.BuildContext.GOPATH); len(list) > 0 && list[0] != "" {
-		modfetch.PkgMod = filepath.Join(list[0], "pkg/mod")
-		codehost.WorkRoot = filepath.Join(list[0], "pkg/mod/cache/vcs")
-	}
 }
 
 // WillBeEnabled checks whether modules should be enabled but does not
@@ -555,101 +515,6 @@
 	}
 }
 
-// checkVendorConsistency verifies that the vendor/modules.txt file matches (if
-// go 1.14) or at least does not contradict (go 1.13 or earlier) the
-// requirements and replacements listed in the main module's go.mod file.
-func checkVendorConsistency() {
-	readVendorList()
-
-	pre114 := false
-	if modFile.Go == nil || semver.Compare("v"+modFile.Go.Version, "v1.14") < 0 {
-		// Go versions before 1.14 did not include enough information in
-		// vendor/modules.txt to check for consistency.
-		// If we know that we're on an earlier version, relax the consistency check.
-		pre114 = true
-	}
-
-	vendErrors := new(strings.Builder)
-	vendErrorf := func(mod module.Version, format string, args ...interface{}) {
-		detail := fmt.Sprintf(format, args...)
-		if mod.Version == "" {
-			fmt.Fprintf(vendErrors, "\n\t%s: %s", mod.Path, detail)
-		} else {
-			fmt.Fprintf(vendErrors, "\n\t%s@%s: %s", mod.Path, mod.Version, detail)
-		}
-	}
-
-	for _, r := range modFile.Require {
-		if !vendorMeta[r.Mod].Explicit {
-			if pre114 {
-				// Before 1.14, modules.txt did not indicate whether modules were listed
-				// explicitly in the main module's go.mod file.
-				// However, we can at least detect a version mismatch if packages were
-				// vendored from a non-matching version.
-				if vv, ok := vendorVersion[r.Mod.Path]; ok && vv != r.Mod.Version {
-					vendErrorf(r.Mod, fmt.Sprintf("is explicitly required in go.mod, but vendor/modules.txt indicates %s@%s", r.Mod.Path, vv))
-				}
-			} else {
-				vendErrorf(r.Mod, "is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt")
-			}
-		}
-	}
-
-	describe := func(m module.Version) string {
-		if m.Version == "" {
-			return m.Path
-		}
-		return m.Path + "@" + m.Version
-	}
-
-	// We need to verify *all* replacements that occur in modfile: even if they
-	// don't directly apply to any module in the vendor list, the replacement
-	// go.mod file can affect the selected versions of other (transitive)
-	// dependencies
-	for _, r := range modFile.Replace {
-		vr := vendorMeta[r.Old].Replacement
-		if vr == (module.Version{}) {
-			if pre114 && (r.Old.Version == "" || vendorVersion[r.Old.Path] != r.Old.Version) {
-				// Before 1.14, modules.txt omitted wildcard replacements and
-				// replacements for modules that did not have any packages to vendor.
-			} else {
-				vendErrorf(r.Old, "is replaced in go.mod, but not marked as replaced in vendor/modules.txt")
-			}
-		} else if vr != r.New {
-			vendErrorf(r.Old, "is replaced by %s in go.mod, but marked as replaced by %s in vendor/modules.txt", describe(r.New), describe(vr))
-		}
-	}
-
-	for _, mod := range vendorList {
-		meta := vendorMeta[mod]
-		if meta.Explicit {
-			if _, inGoMod := index.require[mod]; !inGoMod {
-				vendErrorf(mod, "is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod")
-			}
-		}
-	}
-
-	for _, mod := range vendorReplaced {
-		r := Replacement(mod)
-		if r == (module.Version{}) {
-			vendErrorf(mod, "is marked as replaced in vendor/modules.txt, but not replaced in go.mod")
-			continue
-		}
-		if meta := vendorMeta[mod]; r != meta.Replacement {
-			vendErrorf(mod, "is marked as replaced by %s in vendor/modules.txt, but replaced by %s in go.mod", describe(meta.Replacement), describe(r))
-		}
-	}
-
-	if vendErrors.Len() > 0 {
-		base.Fatalf("go: inconsistent vendoring in %s:%s\n\nrun 'go mod vendor' to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory", modRoot, vendErrors)
-	}
-}
-
-// Allowed reports whether module m is allowed (not excluded) by the main module's go.mod.
-func Allowed(m module.Version) bool {
-	return index == nil || !index.exclude[m]
-}
-
 func legacyModInit() {
 	if modFile == nil {
 		path, err := findModulePath(modRoot)
@@ -740,13 +605,14 @@
 		panic("dir not set")
 	}
 	dir = filepath.Clean(dir)
+	if rel := search.InDir(dir, cfg.BuildContext.GOROOT); rel != "" {
+		// Don't suggest creating a module from $GOROOT/.git/config
+		// or a config file found in any parent of $GOROOT (see #34191).
+		return "", ""
+	}
 	for {
 		for _, name := range altConfigs {
 			if fi, err := os.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() {
-				if rel := search.InDir(dir, cfg.BuildContext.GOROOT); rel == "." {
-					// Don't suggest creating a module from $GOROOT/.git/config.
-					return "", ""
-				}
 				return dir, name
 			}
 		}
@@ -983,113 +849,3 @@
 		base.Fatalf("go: updating go.mod: %v", err)
 	}
 }
-
-// indexModFile rebuilds the index of modFile.
-// If modFile has been changed since it was first read,
-// modFile.Cleanup must be called before indexModFile.
-func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileIndex {
-	i := new(modFileIndex)
-	i.data = data
-	i.dataNeedsFix = needsFix
-
-	i.module = module.Version{}
-	if modFile.Module != nil {
-		i.module = modFile.Module.Mod
-	}
-
-	i.goVersion = ""
-	if modFile.Go != nil {
-		i.goVersion = modFile.Go.Version
-	}
-
-	i.require = make(map[module.Version]requireMeta, len(modFile.Require))
-	for _, r := range modFile.Require {
-		i.require[r.Mod] = requireMeta{indirect: r.Indirect}
-	}
-
-	i.replace = make(map[module.Version]module.Version, len(modFile.Replace))
-	for _, r := range modFile.Replace {
-		if prev, dup := i.replace[r.Old]; dup && prev != r.New {
-			base.Fatalf("go: conflicting replacements for %v:\n\t%v\n\t%v", r.Old, prev, r.New)
-		}
-		i.replace[r.Old] = r.New
-	}
-
-	i.exclude = make(map[module.Version]bool, len(modFile.Exclude))
-	for _, x := range modFile.Exclude {
-		i.exclude[x.Mod] = true
-	}
-
-	return i
-}
-
-// modFileIsDirty reports whether the go.mod file differs meaningfully
-// from what was indexed.
-// If modFile has been changed (even cosmetically) since it was first read,
-// modFile.Cleanup must be called before modFileIsDirty.
-func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool {
-	if i == nil {
-		return modFile != nil
-	}
-
-	if i.dataNeedsFix {
-		return true
-	}
-
-	if modFile.Module == nil {
-		if i.module != (module.Version{}) {
-			return true
-		}
-	} else if modFile.Module.Mod != i.module {
-		return true
-	}
-
-	if modFile.Go == nil {
-		if i.goVersion != "" {
-			return true
-		}
-	} else if modFile.Go.Version != i.goVersion {
-		if i.goVersion == "" && cfg.BuildMod == "readonly" {
-			// go.mod files did not always require a 'go' version, so do not error out
-			// if one is missing — we may be inside an older module in the module
-			// cache, and should bias toward providing useful behavior.
-		} else {
-			return true
-		}
-	}
-
-	if len(modFile.Require) != len(i.require) ||
-		len(modFile.Replace) != len(i.replace) ||
-		len(modFile.Exclude) != len(i.exclude) {
-		return true
-	}
-
-	for _, r := range modFile.Require {
-		if meta, ok := i.require[r.Mod]; !ok {
-			return true
-		} else if r.Indirect != meta.indirect {
-			if cfg.BuildMod == "readonly" {
-				// The module's requirements are consistent; only the "// indirect"
-				// comments that are wrong. But those are only guaranteed to be accurate
-				// after a "go mod tidy" — it's a good idea to run those before
-				// committing a change, but it's certainly not mandatory.
-			} else {
-				return true
-			}
-		}
-	}
-
-	for _, r := range modFile.Replace {
-		if r.New != i.replace[r.Old] {
-			return true
-		}
-	}
-
-	for _, x := range modFile.Exclude {
-		if !i.exclude[x.Mod] {
-			return true
-		}
-	}
-
-	return false
-}
diff --git a/libgo/go/cmd/go/internal/modload/load.go b/libgo/go/cmd/go/internal/modload/load.go
index 7a8391d..f5f74ba 100644
--- a/libgo/go/cmd/go/internal/modload/load.go
+++ b/libgo/go/cmd/go/internal/modload/load.go
@@ -6,18 +6,6 @@
 
 import (
 	"bytes"
-	"errors"
-	"fmt"
-	"go/build"
-	"io/ioutil"
-	"os"
-	"path"
-	pathpkg "path"
-	"path/filepath"
-	"sort"
-	"strings"
-	"sync"
-
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/imports"
@@ -26,10 +14,17 @@
 	"cmd/go/internal/par"
 	"cmd/go/internal/search"
 	"cmd/go/internal/str"
+	"errors"
+	"fmt"
+	"go/build"
+	"os"
+	"path"
+	pathpkg "path"
+	"path/filepath"
+	"sort"
+	"strings"
 
-	"golang.org/x/mod/modfile"
 	"golang.org/x/mod/module"
-	"golang.org/x/mod/semver"
 )
 
 // buildList is the list of modules to use for building packages.
@@ -65,23 +60,13 @@
 // packages. The build tags should typically be imports.Tags() or
 // imports.AnyTags(); a nil map has no special meaning.
 func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match {
-	var fsDirs [][]string
 	updateMatches := func(matches []*search.Match, iterating bool) {
-		for i, m := range matches {
+		for _, m := range matches {
 			switch {
-			case build.IsLocalImport(m.Pattern) || filepath.IsAbs(m.Pattern):
+			case m.IsLocal():
 				// Evaluate list of file system directories on first iteration.
-				if fsDirs == nil {
-					fsDirs = make([][]string, len(matches))
-				}
-				if fsDirs[i] == nil {
-					var dirs []string
-					if m.Literal {
-						dirs = []string{m.Pattern}
-					} else {
-						dirs = search.MatchPackagesInFS(m.Pattern).Pkgs
-					}
-					fsDirs[i] = dirs
+				if m.Dirs == nil {
+					matchLocalDirs(m)
 				}
 
 				// Make a copy of the directory list and translate to import paths.
@@ -90,102 +75,53 @@
 				// from not being in the build list to being in it and back as
 				// the exact version of a particular module increases during
 				// the loader iterations.
-				m.Pkgs = str.StringList(fsDirs[i])
-				pkgs := m.Pkgs
 				m.Pkgs = m.Pkgs[:0]
-				for _, pkg := range pkgs {
-					var dir string
-					if !filepath.IsAbs(pkg) {
-						dir = filepath.Join(base.Cwd, pkg)
-					} else {
-						dir = filepath.Clean(pkg)
-					}
+				for _, dir := range m.Dirs {
+					pkg, err := resolveLocalPackage(dir)
+					if err != nil {
+						if !m.IsLiteral() && (err == errPkgIsBuiltin || err == errPkgIsGorootSrc) {
+							continue // Don't include "builtin" or GOROOT/src in wildcard patterns.
+						}
 
-					// golang.org/issue/32917: We should resolve a relative path to a
-					// package path only if the relative path actually contains the code
-					// for that package.
-					if !dirContainsPackage(dir) {
 						// If we're outside of a module, ensure that the failure mode
 						// indicates that.
 						ModRoot()
 
-						// If the directory is local but does not exist, don't return it
-						// while loader is iterating, since this might trigger a fetch.
-						// After loader is done iterating, we still need to return the
-						// path, so that "go list -e" produces valid output.
 						if !iterating {
-							// We don't have a valid path to resolve to, so report the
-							// unresolved path.
-							m.Pkgs = append(m.Pkgs, pkg)
+							m.AddError(err)
 						}
 						continue
 					}
-
-					// Note: The checks for @ here are just to avoid misinterpreting
-					// the module cache directories (formerly GOPATH/src/mod/foo@v1.5.2/bar).
-					// It's not strictly necessary but helpful to keep the checks.
-					if modRoot != "" && dir == modRoot {
-						pkg = targetPrefix
-					} else if modRoot != "" && strings.HasPrefix(dir, modRoot+string(filepath.Separator)) && !strings.Contains(dir[len(modRoot):], "@") {
-						suffix := filepath.ToSlash(dir[len(modRoot):])
-						if strings.HasPrefix(suffix, "/vendor/") {
-							// TODO getmode vendor check
-							pkg = strings.TrimPrefix(suffix, "/vendor/")
-						} else if targetInGorootSrc && Target.Path == "std" {
-							// Don't add the prefix "std/" to packages in the "std" module.
-							// It's the one module path that isn't a prefix of its packages.
-							pkg = strings.TrimPrefix(suffix, "/")
-							if pkg == "builtin" {
-								// "builtin" is a pseudo-package with a real source file.
-								// It's not included in "std", so it shouldn't be included in
-								// "./..." within module "std" either.
-								continue
-							}
-						} else {
-							modPkg := targetPrefix + suffix
-							if _, ok := dirInModule(modPkg, targetPrefix, modRoot, true); ok {
-								pkg = modPkg
-							} else if !iterating {
-								ModRoot()
-								base.Errorf("go: directory %s is outside main module", base.ShortPath(dir))
-							}
-						}
-					} else if sub := search.InDir(dir, cfg.GOROOTsrc); sub != "" && sub != "." && !strings.Contains(sub, "@") {
-						pkg = filepath.ToSlash(sub)
-					} else if path := pathInModuleCache(dir); path != "" {
-						pkg = path
-					} else {
-						pkg = ""
-						if !iterating {
-							ModRoot()
-							base.Errorf("go: directory %s outside available modules", base.ShortPath(dir))
-						}
-					}
 					m.Pkgs = append(m.Pkgs, pkg)
 				}
 
-			case strings.Contains(m.Pattern, "..."):
-				m.Pkgs = matchPackages(m.Pattern, loaded.tags, true, buildList)
+			case m.IsLiteral():
+				m.Pkgs = []string{m.Pattern()}
 
-			case m.Pattern == "all":
+			case strings.Contains(m.Pattern(), "..."):
+				m.Errs = m.Errs[:0]
+				matchPackages(m, loaded.tags, includeStd, buildList)
+
+			case m.Pattern() == "all":
 				loaded.testAll = true
 				if iterating {
 					// Enumerate the packages in the main module.
 					// We'll load the dependencies as we find them.
-					m.Pkgs = matchPackages("...", loaded.tags, false, []module.Version{Target})
+					m.Errs = m.Errs[:0]
+					matchPackages(m, loaded.tags, omitStd, []module.Version{Target})
 				} else {
 					// Starting with the packages in the main module,
 					// enumerate the full list of "all".
 					m.Pkgs = loaded.computePatternAll(m.Pkgs)
 				}
 
-			case search.IsMetaPackage(m.Pattern): // std, cmd
-				if len(m.Pkgs) == 0 {
-					m.Pkgs = search.MatchPackages(m.Pattern).Pkgs
+			case m.Pattern() == "std" || m.Pattern() == "cmd":
+				if m.Pkgs == nil {
+					m.MatchPackages() // Locate the packages within GOROOT/src.
 				}
 
 			default:
-				m.Pkgs = []string{m.Pattern}
+				panic(fmt.Sprintf("internal error: modload missing case for pattern %s", m.Pattern()))
 			}
 		}
 	}
@@ -194,10 +130,7 @@
 
 	var matches []*search.Match
 	for _, pattern := range search.CleanPatterns(patterns) {
-		matches = append(matches, &search.Match{
-			Pattern: pattern,
-			Literal: !strings.Contains(pattern, "...") && !search.IsMetaPackage(pattern),
-		})
+		matches = append(matches, search.NewMatch(pattern))
 	}
 
 	loaded = newLoader(tags)
@@ -238,6 +171,139 @@
 	base.ExitIfErrors()
 }
 
+// matchLocalDirs is like m.MatchDirs, but tries to avoid scanning directories
+// outside of the standard library and active modules.
+func matchLocalDirs(m *search.Match) {
+	if !m.IsLocal() {
+		panic(fmt.Sprintf("internal error: resolveLocalDirs on non-local pattern %s", m.Pattern()))
+	}
+
+	if i := strings.Index(m.Pattern(), "..."); i >= 0 {
+		// The pattern is local, but it is a wildcard. Its packages will
+		// only resolve to paths if they are inside of the standard
+		// library, the main module, or some dependency of the main
+		// module. Verify that before we walk the filesystem: a filesystem
+		// walk in a directory like /var or /etc can be very expensive!
+		dir := filepath.Dir(filepath.Clean(m.Pattern()[:i+3]))
+		absDir := dir
+		if !filepath.IsAbs(dir) {
+			absDir = filepath.Join(base.Cwd, dir)
+		}
+		if search.InDir(absDir, cfg.GOROOTsrc) == "" && search.InDir(absDir, ModRoot()) == "" && pathInModuleCache(absDir) == "" {
+			m.Dirs = []string{}
+			m.AddError(fmt.Errorf("directory prefix %s outside available modules", base.ShortPath(absDir)))
+			return
+		}
+	}
+
+	m.MatchDirs()
+}
+
+// resolveLocalPackage resolves a filesystem path to a package path.
+func resolveLocalPackage(dir string) (string, error) {
+	var absDir string
+	if filepath.IsAbs(dir) {
+		absDir = filepath.Clean(dir)
+	} else {
+		absDir = filepath.Join(base.Cwd, dir)
+	}
+
+	bp, err := cfg.BuildContext.ImportDir(absDir, 0)
+	if err != nil && (bp == nil || len(bp.IgnoredGoFiles) == 0) {
+		// golang.org/issue/32917: We should resolve a relative path to a
+		// package path only if the relative path actually contains the code
+		// for that package.
+		//
+		// If the named directory does not exist or contains no Go files,
+		// the package does not exist.
+		// Other errors may affect package loading, but not resolution.
+		if _, err := os.Stat(absDir); err != nil {
+			if os.IsNotExist(err) {
+				// Canonicalize OS-specific errors to errDirectoryNotFound so that error
+				// messages will be easier for users to search for.
+				return "", &os.PathError{Op: "stat", Path: absDir, Err: errDirectoryNotFound}
+			}
+			return "", err
+		}
+		if _, noGo := err.(*build.NoGoError); noGo {
+			// A directory that does not contain any Go source files — even ignored
+			// ones! — is not a Go package, and we can't resolve it to a package
+			// path because that path could plausibly be provided by some other
+			// module.
+			//
+			// Any other error indicates that the package “exists” (at least in the
+			// sense that it cannot exist in any other module), but has some other
+			// problem (such as a syntax error).
+			return "", err
+		}
+	}
+
+	if modRoot != "" && absDir == modRoot {
+		if absDir == cfg.GOROOTsrc {
+			return "", errPkgIsGorootSrc
+		}
+		return targetPrefix, nil
+	}
+
+	// Note: The checks for @ here are just to avoid misinterpreting
+	// the module cache directories (formerly GOPATH/src/mod/foo@v1.5.2/bar).
+	// It's not strictly necessary but helpful to keep the checks.
+	if modRoot != "" && strings.HasPrefix(absDir, modRoot+string(filepath.Separator)) && !strings.Contains(absDir[len(modRoot):], "@") {
+		suffix := filepath.ToSlash(absDir[len(modRoot):])
+		if strings.HasPrefix(suffix, "/vendor/") {
+			if cfg.BuildMod != "vendor" {
+				return "", fmt.Errorf("without -mod=vendor, directory %s has no package path", absDir)
+			}
+
+			readVendorList()
+			pkg := strings.TrimPrefix(suffix, "/vendor/")
+			if _, ok := vendorPkgModule[pkg]; !ok {
+				return "", fmt.Errorf("directory %s is not a package listed in vendor/modules.txt", absDir)
+			}
+			return pkg, nil
+		}
+
+		if targetPrefix == "" {
+			pkg := strings.TrimPrefix(suffix, "/")
+			if pkg == "builtin" {
+				// "builtin" is a pseudo-package with a real source file.
+				// It's not included in "std", so it shouldn't resolve from "."
+				// within module "std" either.
+				return "", errPkgIsBuiltin
+			}
+			return pkg, nil
+		}
+
+		pkg := targetPrefix + suffix
+		if _, ok, err := dirInModule(pkg, targetPrefix, modRoot, true); err != nil {
+			return "", err
+		} else if !ok {
+			return "", &PackageNotInModuleError{Mod: Target, Pattern: pkg}
+		}
+		return pkg, nil
+	}
+
+	if sub := search.InDir(absDir, cfg.GOROOTsrc); sub != "" && sub != "." && !strings.Contains(sub, "@") {
+		pkg := filepath.ToSlash(sub)
+		if pkg == "builtin" {
+			return "", errPkgIsBuiltin
+		}
+		return pkg, nil
+	}
+
+	pkg := pathInModuleCache(absDir)
+	if pkg == "" {
+		return "", fmt.Errorf("directory %s outside available modules", base.ShortPath(absDir))
+	}
+	return pkg, nil
+}
+
+var (
+	errDirectoryNotFound = errors.New("directory not found")
+	errPkgIsGorootSrc    = errors.New("GOROOT/src is not an importable package")
+	errPkgIsBuiltin      = errors.New(`"builtin" is a pseudo-package, not an importable package`)
+)
+
 // pathInModuleCache returns the import path of the directory dir,
 // if dir is in the module cache copy of a module in our build list.
 func pathInModuleCache(dir string) string {
@@ -267,32 +333,6 @@
 	return ""
 }
 
-var dirContainsPackageCache sync.Map // absolute dir → bool
-
-func dirContainsPackage(dir string) bool {
-	isPkg, ok := dirContainsPackageCache.Load(dir)
-	if !ok {
-		_, err := cfg.BuildContext.ImportDir(dir, 0)
-		if err == nil {
-			isPkg = true
-		} else {
-			if fi, statErr := os.Stat(dir); statErr != nil || !fi.IsDir() {
-				// A non-directory or inaccessible directory is not a Go package.
-				isPkg = false
-			} else if _, noGo := err.(*build.NoGoError); noGo {
-				// A directory containing no Go source files is not a Go package.
-				isPkg = false
-			} else {
-				// An error other than *build.NoGoError indicates that the package exists
-				// but has some other problem (such as a syntax error).
-				isPkg = true
-			}
-		}
-		isPkg, _ = dirContainsPackageCache.LoadOrStore(dir, isPkg)
-	}
-	return isPkg.(bool)
-}
-
 // ImportFromFiles adds modules to the build list as needed
 // to satisfy the imports in the named Go source files.
 func ImportFromFiles(gofiles []string) {
@@ -386,7 +426,7 @@
 		loaded.testRoots = true
 	}
 	all := TargetPackages("...")
-	loaded.load(func() []string { return all })
+	loaded.load(func() []string { return all.Pkgs })
 	checkMultiplePaths()
 	WriteGoMod()
 
@@ -398,6 +438,9 @@
 		}
 		paths = append(paths, pkg.path)
 	}
+	for _, err := range all.Errs {
+		base.Errorf("%v", err)
+	}
 	base.ExitIfErrors()
 	return paths
 }
@@ -405,12 +448,14 @@
 // TargetPackages returns the list of packages in the target (top-level) module
 // matching pattern, which may be relative to the working directory, under all
 // build tag settings.
-func TargetPackages(pattern string) []string {
+func TargetPackages(pattern string) *search.Match {
 	// TargetPackages is relative to the main module, so ensure that the main
 	// module is a thing that can contain packages.
 	ModRoot()
 
-	return matchPackages(pattern, imports.AnyTags(), false, []module.Version{Target})
+	m := search.NewMatch(pattern)
+	matchPackages(m, imports.AnyTags(), omitStd, []module.Version{Target})
+	return m
 }
 
 // BuildList returns the module build list,
@@ -655,13 +700,13 @@
 				if err.newMissingVersion != "" {
 					base.Fatalf("go: %s: package provided by %s at latest version %s but not at required version %s", pkg.stackText(), err.Module.Path, err.Module.Version, err.newMissingVersion)
 				}
+				fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, err.Module.Path, err.Module.Version)
 				if added[pkg.path] {
 					base.Fatalf("go: %s: looping trying to add package", pkg.stackText())
 				}
 				added[pkg.path] = true
 				numAdded++
 				if !haveMod[err.Module] {
-					fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, err.Module.Path, err.Module.Version)
 					haveMod[err.Module] = true
 					modAddedBy[err.Module] = pkg
 					buildList = append(buildList, err.Module)
@@ -761,7 +806,7 @@
 			// Leave for error during load.
 			return
 		}
-		if build.IsLocalImport(pkg.path) {
+		if build.IsLocalImport(pkg.path) || filepath.IsAbs(pkg.path) {
 			// Leave for error during load.
 			// (Module mode does not allow local imports.)
 			return
@@ -996,354 +1041,3 @@
 	}
 	return n
 }
-
-// Replacement returns the replacement for mod, if any, from go.mod.
-// If there is no replacement for mod, Replacement returns
-// a module.Version with Path == "".
-func Replacement(mod module.Version) module.Version {
-	if index != nil {
-		if r, ok := index.replace[mod]; ok {
-			return r
-		}
-		if r, ok := index.replace[module.Version{Path: mod.Path}]; ok {
-			return r
-		}
-	}
-	return module.Version{}
-}
-
-// mvsReqs implements mvs.Reqs for module semantic versions,
-// with any exclusions or replacements applied internally.
-type mvsReqs struct {
-	buildList []module.Version
-	cache     par.Cache
-	versions  sync.Map
-}
-
-// Reqs returns the current module requirement graph.
-// Future calls to SetBuildList do not affect the operation
-// of the returned Reqs.
-func Reqs() mvs.Reqs {
-	r := &mvsReqs{
-		buildList: buildList,
-	}
-	return r
-}
-
-func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
-	type cached struct {
-		list []module.Version
-		err  error
-	}
-
-	c := r.cache.Do(mod, func() interface{} {
-		list, err := r.required(mod)
-		if err != nil {
-			return cached{nil, err}
-		}
-		for i, mv := range list {
-			if index != nil {
-				for index.exclude[mv] {
-					mv1, err := r.next(mv)
-					if err != nil {
-						return cached{nil, err}
-					}
-					if mv1.Version == "none" {
-						return cached{nil, fmt.Errorf("%s(%s) depends on excluded %s(%s) with no newer version available", mod.Path, mod.Version, mv.Path, mv.Version)}
-					}
-					mv = mv1
-				}
-			}
-			list[i] = mv
-		}
-
-		return cached{list, nil}
-	}).(cached)
-
-	return c.list, c.err
-}
-
-var vendorOnce sync.Once
-
-type vendorMetadata struct {
-	Explicit    bool
-	Replacement module.Version
-}
-
-var (
-	vendorList      []module.Version          // modules that contribute packages to the build, in order of appearance
-	vendorReplaced  []module.Version          // all replaced modules; may or may not also contribute packages
-	vendorVersion   map[string]string         // module path → selected version (if known)
-	vendorPkgModule map[string]module.Version // package → containing module
-	vendorMeta      map[module.Version]vendorMetadata
-)
-
-// readVendorList reads the list of vendored modules from vendor/modules.txt.
-func readVendorList() {
-	vendorOnce.Do(func() {
-		vendorList = nil
-		vendorPkgModule = make(map[string]module.Version)
-		vendorVersion = make(map[string]string)
-		vendorMeta = make(map[module.Version]vendorMetadata)
-		data, err := ioutil.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt"))
-		if err != nil {
-			if !errors.Is(err, os.ErrNotExist) {
-				base.Fatalf("go: %s", err)
-			}
-			return
-		}
-
-		var mod module.Version
-		for _, line := range strings.Split(string(data), "\n") {
-			if strings.HasPrefix(line, "# ") {
-				f := strings.Fields(line)
-
-				if len(f) < 3 {
-					continue
-				}
-				if semver.IsValid(f[2]) {
-					// A module, but we don't yet know whether it is in the build list or
-					// only included to indicate a replacement.
-					mod = module.Version{Path: f[1], Version: f[2]}
-					f = f[3:]
-				} else if f[2] == "=>" {
-					// A wildcard replacement found in the main module's go.mod file.
-					mod = module.Version{Path: f[1]}
-					f = f[2:]
-				} else {
-					// Not a version or a wildcard replacement.
-					// We don't know how to interpret this module line, so ignore it.
-					mod = module.Version{}
-					continue
-				}
-
-				if len(f) >= 2 && f[0] == "=>" {
-					meta := vendorMeta[mod]
-					if len(f) == 2 {
-						// File replacement.
-						meta.Replacement = module.Version{Path: f[1]}
-						vendorReplaced = append(vendorReplaced, mod)
-					} else if len(f) == 3 && semver.IsValid(f[2]) {
-						// Path and version replacement.
-						meta.Replacement = module.Version{Path: f[1], Version: f[2]}
-						vendorReplaced = append(vendorReplaced, mod)
-					} else {
-						// We don't understand this replacement. Ignore it.
-					}
-					vendorMeta[mod] = meta
-				}
-				continue
-			}
-
-			// Not a module line. Must be a package within a module or a metadata
-			// directive, either of which requires a preceding module line.
-			if mod.Path == "" {
-				continue
-			}
-
-			if strings.HasPrefix(line, "## ") {
-				// Metadata. Take the union of annotations across multiple lines, if present.
-				meta := vendorMeta[mod]
-				for _, entry := range strings.Split(strings.TrimPrefix(line, "## "), ";") {
-					entry = strings.TrimSpace(entry)
-					if entry == "explicit" {
-						meta.Explicit = true
-					}
-					// All other tokens are reserved for future use.
-				}
-				vendorMeta[mod] = meta
-				continue
-			}
-
-			if f := strings.Fields(line); len(f) == 1 && module.CheckImportPath(f[0]) == nil {
-				// A package within the current module.
-				vendorPkgModule[f[0]] = mod
-
-				// Since this module provides a package for the build, we know that it
-				// is in the build list and is the selected version of its path.
-				// If this information is new, record it.
-				if v, ok := vendorVersion[mod.Path]; !ok || semver.Compare(v, mod.Version) < 0 {
-					vendorList = append(vendorList, mod)
-					vendorVersion[mod.Path] = mod.Version
-				}
-			}
-		}
-	})
-}
-
-func (r *mvsReqs) modFileToList(f *modfile.File) []module.Version {
-	list := make([]module.Version, 0, len(f.Require))
-	for _, r := range f.Require {
-		list = append(list, r.Mod)
-	}
-	return list
-}
-
-// required returns a unique copy of the requirements of mod.
-func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) {
-	if mod == Target {
-		if modFile != nil && modFile.Go != nil {
-			r.versions.LoadOrStore(mod, modFile.Go.Version)
-		}
-		return append([]module.Version(nil), r.buildList[1:]...), nil
-	}
-
-	if cfg.BuildMod == "vendor" {
-		// For every module other than the target,
-		// return the full list of modules from modules.txt.
-		readVendorList()
-		return append([]module.Version(nil), vendorList...), nil
-	}
-
-	origPath := mod.Path
-	if repl := Replacement(mod); repl.Path != "" {
-		if repl.Version == "" {
-			// TODO: need to slip the new version into the tags list etc.
-			dir := repl.Path
-			if !filepath.IsAbs(dir) {
-				dir = filepath.Join(ModRoot(), dir)
-			}
-			gomod := filepath.Join(dir, "go.mod")
-			data, err := ioutil.ReadFile(gomod)
-			if err != nil {
-				return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err)
-			}
-			f, err := modfile.ParseLax(gomod, data, nil)
-			if err != nil {
-				return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err)
-			}
-			if f.Go != nil {
-				r.versions.LoadOrStore(mod, f.Go.Version)
-			}
-			return r.modFileToList(f), nil
-		}
-		mod = repl
-	}
-
-	if mod.Version == "none" {
-		return nil, nil
-	}
-
-	if !semver.IsValid(mod.Version) {
-		// Disallow the broader queries supported by fetch.Lookup.
-		base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", mod.Path, mod.Version)
-	}
-
-	data, err := modfetch.GoMod(mod.Path, mod.Version)
-	if err != nil {
-		return nil, err
-	}
-	f, err := modfile.ParseLax("go.mod", data, nil)
-	if err != nil {
-		return nil, module.VersionError(mod, fmt.Errorf("parsing go.mod: %v", err))
-	}
-
-	if f.Module == nil {
-		return nil, module.VersionError(mod, errors.New("parsing go.mod: missing module line"))
-	}
-	if mpath := f.Module.Mod.Path; mpath != origPath && mpath != mod.Path {
-		return nil, module.VersionError(mod, fmt.Errorf(`parsing go.mod:
-	module declares its path as: %s
-	        but was required as: %s`, mpath, mod.Path))
-	}
-	if f.Go != nil {
-		r.versions.LoadOrStore(mod, f.Go.Version)
-	}
-
-	return r.modFileToList(f), nil
-}
-
-func (*mvsReqs) Max(v1, v2 string) string {
-	if v1 != "" && semver.Compare(v1, v2) == -1 {
-		return v2
-	}
-	return v1
-}
-
-// Upgrade is a no-op, here to implement mvs.Reqs.
-// The upgrade logic for go get -u is in ../modget/get.go.
-func (*mvsReqs) Upgrade(m module.Version) (module.Version, error) {
-	return m, nil
-}
-
-func versions(path string) ([]string, error) {
-	// Note: modfetch.Lookup and repo.Versions are cached,
-	// so there's no need for us to add extra caching here.
-	var versions []string
-	err := modfetch.TryProxies(func(proxy string) error {
-		repo, err := modfetch.Lookup(proxy, path)
-		if err == nil {
-			versions, err = repo.Versions("")
-		}
-		return err
-	})
-	return versions, err
-}
-
-// Previous returns the tagged version of m.Path immediately prior to
-// m.Version, or version "none" if no prior version is tagged.
-func (*mvsReqs) Previous(m module.Version) (module.Version, error) {
-	list, err := versions(m.Path)
-	if err != nil {
-		return module.Version{}, err
-	}
-	i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) >= 0 })
-	if i > 0 {
-		return module.Version{Path: m.Path, Version: list[i-1]}, nil
-	}
-	return module.Version{Path: m.Path, Version: "none"}, nil
-}
-
-// next returns the next version of m.Path after m.Version.
-// It is only used by the exclusion processing in the Required method,
-// not called directly by MVS.
-func (*mvsReqs) next(m module.Version) (module.Version, error) {
-	list, err := versions(m.Path)
-	if err != nil {
-		return module.Version{}, err
-	}
-	i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) > 0 })
-	if i < len(list) {
-		return module.Version{Path: m.Path, Version: list[i]}, nil
-	}
-	return module.Version{Path: m.Path, Version: "none"}, nil
-}
-
-// fetch downloads the given module (or its replacement)
-// and returns its location.
-//
-// The isLocal return value reports whether the replacement,
-// if any, is local to the filesystem.
-func fetch(mod module.Version) (dir string, isLocal bool, err error) {
-	if mod == Target {
-		return ModRoot(), true, nil
-	}
-	if r := Replacement(mod); r.Path != "" {
-		if r.Version == "" {
-			dir = r.Path
-			if !filepath.IsAbs(dir) {
-				dir = filepath.Join(ModRoot(), dir)
-			}
-			// Ensure that the replacement directory actually exists:
-			// dirInModule does not report errors for missing modules,
-			// so if we don't report the error now, later failures will be
-			// very mysterious.
-			if _, err := os.Stat(dir); err != nil {
-				if os.IsNotExist(err) {
-					// Semantically the module version itself “exists” — we just don't
-					// have its source code. Remove the equivalence to os.ErrNotExist,
-					// and make the message more concise while we're at it.
-					err = fmt.Errorf("replacement directory %s does not exist", r.Path)
-				} else {
-					err = fmt.Errorf("replacement directory %s: %w", r.Path, err)
-				}
-				return dir, true, module.VersionError(mod, err)
-			}
-			return dir, true, nil
-		}
-		mod = r
-	}
-
-	dir, err = modfetch.Download(mod)
-	return dir, false, err
-}
diff --git a/libgo/go/cmd/go/internal/modload/modfile.go b/libgo/go/cmd/go/internal/modload/modfile.go
new file mode 100644
index 0000000..9f4ec5a
--- /dev/null
+++ b/libgo/go/cmd/go/internal/modload/modfile.go
@@ -0,0 +1,164 @@
+// 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.
+
+package modload
+
+import (
+	"cmd/go/internal/base"
+	"cmd/go/internal/cfg"
+
+	"golang.org/x/mod/modfile"
+	"golang.org/x/mod/module"
+)
+
+var modFile *modfile.File
+
+// A modFileIndex is an index of data corresponding to a modFile
+// at a specific point in time.
+type modFileIndex struct {
+	data         []byte
+	dataNeedsFix bool // true if fixVersion applied a change while parsing data
+	module       module.Version
+	goVersion    string
+	require      map[module.Version]requireMeta
+	replace      map[module.Version]module.Version
+	exclude      map[module.Version]bool
+}
+
+// index is the index of the go.mod file as of when it was last read or written.
+var index *modFileIndex
+
+type requireMeta struct {
+	indirect bool
+}
+
+// Allowed reports whether module m is allowed (not excluded) by the main module's go.mod.
+func Allowed(m module.Version) bool {
+	return index == nil || !index.exclude[m]
+}
+
+// Replacement returns the replacement for mod, if any, from go.mod.
+// If there is no replacement for mod, Replacement returns
+// a module.Version with Path == "".
+func Replacement(mod module.Version) module.Version {
+	if index != nil {
+		if r, ok := index.replace[mod]; ok {
+			return r
+		}
+		if r, ok := index.replace[module.Version{Path: mod.Path}]; ok {
+			return r
+		}
+	}
+	return module.Version{}
+}
+
+// indexModFile rebuilds the index of modFile.
+// If modFile has been changed since it was first read,
+// modFile.Cleanup must be called before indexModFile.
+func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileIndex {
+	i := new(modFileIndex)
+	i.data = data
+	i.dataNeedsFix = needsFix
+
+	i.module = module.Version{}
+	if modFile.Module != nil {
+		i.module = modFile.Module.Mod
+	}
+
+	i.goVersion = ""
+	if modFile.Go != nil {
+		i.goVersion = modFile.Go.Version
+	}
+
+	i.require = make(map[module.Version]requireMeta, len(modFile.Require))
+	for _, r := range modFile.Require {
+		i.require[r.Mod] = requireMeta{indirect: r.Indirect}
+	}
+
+	i.replace = make(map[module.Version]module.Version, len(modFile.Replace))
+	for _, r := range modFile.Replace {
+		if prev, dup := i.replace[r.Old]; dup && prev != r.New {
+			base.Fatalf("go: conflicting replacements for %v:\n\t%v\n\t%v", r.Old, prev, r.New)
+		}
+		i.replace[r.Old] = r.New
+	}
+
+	i.exclude = make(map[module.Version]bool, len(modFile.Exclude))
+	for _, x := range modFile.Exclude {
+		i.exclude[x.Mod] = true
+	}
+
+	return i
+}
+
+// modFileIsDirty reports whether the go.mod file differs meaningfully
+// from what was indexed.
+// If modFile has been changed (even cosmetically) since it was first read,
+// modFile.Cleanup must be called before modFileIsDirty.
+func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool {
+	if i == nil {
+		return modFile != nil
+	}
+
+	if i.dataNeedsFix {
+		return true
+	}
+
+	if modFile.Module == nil {
+		if i.module != (module.Version{}) {
+			return true
+		}
+	} else if modFile.Module.Mod != i.module {
+		return true
+	}
+
+	if modFile.Go == nil {
+		if i.goVersion != "" {
+			return true
+		}
+	} else if modFile.Go.Version != i.goVersion {
+		if i.goVersion == "" && cfg.BuildMod == "readonly" {
+			// go.mod files did not always require a 'go' version, so do not error out
+			// if one is missing — we may be inside an older module in the module
+			// cache, and should bias toward providing useful behavior.
+		} else {
+			return true
+		}
+	}
+
+	if len(modFile.Require) != len(i.require) ||
+		len(modFile.Replace) != len(i.replace) ||
+		len(modFile.Exclude) != len(i.exclude) {
+		return true
+	}
+
+	for _, r := range modFile.Require {
+		if meta, ok := i.require[r.Mod]; !ok {
+			return true
+		} else if r.Indirect != meta.indirect {
+			if cfg.BuildMod == "readonly" {
+				// The module's requirements are consistent; only the "// indirect"
+				// comments that are wrong. But those are only guaranteed to be accurate
+				// after a "go mod tidy" — it's a good idea to run those before
+				// committing a change, but it's certainly not mandatory.
+			} else {
+				return true
+			}
+		}
+	}
+
+	for _, r := range modFile.Replace {
+		if r.New != i.replace[r.Old] {
+			return true
+		}
+	}
+
+	for _, x := range modFile.Exclude {
+		if !i.exclude[x.Mod] {
+			return true
+		}
+	}
+
+	return false
+}
diff --git a/libgo/go/cmd/go/internal/modload/mvs.go b/libgo/go/cmd/go/internal/modload/mvs.go
new file mode 100644
index 0000000..5dd009d
--- /dev/null
+++ b/libgo/go/cmd/go/internal/modload/mvs.go
@@ -0,0 +1,259 @@
+// 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.
+
+package modload
+
+import (
+	"errors"
+	"fmt"
+	"os"
+	"path/filepath"
+	"sort"
+	"sync"
+
+	"cmd/go/internal/base"
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/lockedfile"
+	"cmd/go/internal/modfetch"
+	"cmd/go/internal/mvs"
+	"cmd/go/internal/par"
+
+	"golang.org/x/mod/modfile"
+	"golang.org/x/mod/module"
+	"golang.org/x/mod/semver"
+)
+
+// mvsReqs implements mvs.Reqs for module semantic versions,
+// with any exclusions or replacements applied internally.
+type mvsReqs struct {
+	buildList []module.Version
+	cache     par.Cache
+	versions  sync.Map
+}
+
+// Reqs returns the current module requirement graph.
+// Future calls to SetBuildList do not affect the operation
+// of the returned Reqs.
+func Reqs() mvs.Reqs {
+	r := &mvsReqs{
+		buildList: buildList,
+	}
+	return r
+}
+
+func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
+	type cached struct {
+		list []module.Version
+		err  error
+	}
+
+	c := r.cache.Do(mod, func() interface{} {
+		list, err := r.required(mod)
+		if err != nil {
+			return cached{nil, err}
+		}
+		for i, mv := range list {
+			if index != nil {
+				for index.exclude[mv] {
+					mv1, err := r.next(mv)
+					if err != nil {
+						return cached{nil, err}
+					}
+					if mv1.Version == "none" {
+						return cached{nil, fmt.Errorf("%s(%s) depends on excluded %s(%s) with no newer version available", mod.Path, mod.Version, mv.Path, mv.Version)}
+					}
+					mv = mv1
+				}
+			}
+			list[i] = mv
+		}
+
+		return cached{list, nil}
+	}).(cached)
+
+	return c.list, c.err
+}
+
+func (r *mvsReqs) modFileToList(f *modfile.File) []module.Version {
+	list := make([]module.Version, 0, len(f.Require))
+	for _, r := range f.Require {
+		list = append(list, r.Mod)
+	}
+	return list
+}
+
+// required returns a unique copy of the requirements of mod.
+func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) {
+	if mod == Target {
+		if modFile != nil && modFile.Go != nil {
+			r.versions.LoadOrStore(mod, modFile.Go.Version)
+		}
+		return append([]module.Version(nil), r.buildList[1:]...), nil
+	}
+
+	if cfg.BuildMod == "vendor" {
+		// For every module other than the target,
+		// return the full list of modules from modules.txt.
+		readVendorList()
+		return append([]module.Version(nil), vendorList...), nil
+	}
+
+	origPath := mod.Path
+	if repl := Replacement(mod); repl.Path != "" {
+		if repl.Version == "" {
+			// TODO: need to slip the new version into the tags list etc.
+			dir := repl.Path
+			if !filepath.IsAbs(dir) {
+				dir = filepath.Join(ModRoot(), dir)
+			}
+			gomod := filepath.Join(dir, "go.mod")
+			data, err := lockedfile.Read(gomod)
+			if err != nil {
+				return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err)
+			}
+			f, err := modfile.ParseLax(gomod, data, nil)
+			if err != nil {
+				return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err)
+			}
+			if f.Go != nil {
+				r.versions.LoadOrStore(mod, f.Go.Version)
+			}
+			return r.modFileToList(f), nil
+		}
+		mod = repl
+	}
+
+	if mod.Version == "none" {
+		return nil, nil
+	}
+
+	if !semver.IsValid(mod.Version) {
+		// Disallow the broader queries supported by fetch.Lookup.
+		base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", mod.Path, mod.Version)
+	}
+
+	data, err := modfetch.GoMod(mod.Path, mod.Version)
+	if err != nil {
+		return nil, err
+	}
+	f, err := modfile.ParseLax("go.mod", data, nil)
+	if err != nil {
+		return nil, module.VersionError(mod, fmt.Errorf("parsing go.mod: %v", err))
+	}
+
+	if f.Module == nil {
+		return nil, module.VersionError(mod, errors.New("parsing go.mod: missing module line"))
+	}
+	if mpath := f.Module.Mod.Path; mpath != origPath && mpath != mod.Path {
+		return nil, module.VersionError(mod, fmt.Errorf(`parsing go.mod:
+	module declares its path as: %s
+	        but was required as: %s`, mpath, origPath))
+	}
+	if f.Go != nil {
+		r.versions.LoadOrStore(mod, f.Go.Version)
+	}
+
+	return r.modFileToList(f), nil
+}
+
+// Max returns the maximum of v1 and v2 according to semver.Compare.
+//
+// As a special case, the version "" is considered higher than all other
+// versions. The main module (also known as the target) has no version and must
+// be chosen over other versions of the same module in the module dependency
+// graph.
+func (*mvsReqs) Max(v1, v2 string) string {
+	if v1 != "" && semver.Compare(v1, v2) == -1 {
+		return v2
+	}
+	return v1
+}
+
+// Upgrade is a no-op, here to implement mvs.Reqs.
+// The upgrade logic for go get -u is in ../modget/get.go.
+func (*mvsReqs) Upgrade(m module.Version) (module.Version, error) {
+	return m, nil
+}
+
+func versions(path string) ([]string, error) {
+	// Note: modfetch.Lookup and repo.Versions are cached,
+	// so there's no need for us to add extra caching here.
+	var versions []string
+	err := modfetch.TryProxies(func(proxy string) error {
+		repo, err := modfetch.Lookup(proxy, path)
+		if err == nil {
+			versions, err = repo.Versions("")
+		}
+		return err
+	})
+	return versions, err
+}
+
+// Previous returns the tagged version of m.Path immediately prior to
+// m.Version, or version "none" if no prior version is tagged.
+func (*mvsReqs) Previous(m module.Version) (module.Version, error) {
+	list, err := versions(m.Path)
+	if err != nil {
+		return module.Version{}, err
+	}
+	i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) >= 0 })
+	if i > 0 {
+		return module.Version{Path: m.Path, Version: list[i-1]}, nil
+	}
+	return module.Version{Path: m.Path, Version: "none"}, nil
+}
+
+// next returns the next version of m.Path after m.Version.
+// It is only used by the exclusion processing in the Required method,
+// not called directly by MVS.
+func (*mvsReqs) next(m module.Version) (module.Version, error) {
+	list, err := versions(m.Path)
+	if err != nil {
+		return module.Version{}, err
+	}
+	i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) > 0 })
+	if i < len(list) {
+		return module.Version{Path: m.Path, Version: list[i]}, nil
+	}
+	return module.Version{Path: m.Path, Version: "none"}, nil
+}
+
+// fetch downloads the given module (or its replacement)
+// and returns its location.
+//
+// The isLocal return value reports whether the replacement,
+// if any, is local to the filesystem.
+func fetch(mod module.Version) (dir string, isLocal bool, err error) {
+	if mod == Target {
+		return ModRoot(), true, nil
+	}
+	if r := Replacement(mod); r.Path != "" {
+		if r.Version == "" {
+			dir = r.Path
+			if !filepath.IsAbs(dir) {
+				dir = filepath.Join(ModRoot(), dir)
+			}
+			// Ensure that the replacement directory actually exists:
+			// dirInModule does not report errors for missing modules,
+			// so if we don't report the error now, later failures will be
+			// very mysterious.
+			if _, err := os.Stat(dir); err != nil {
+				if os.IsNotExist(err) {
+					// Semantically the module version itself “exists” — we just don't
+					// have its source code. Remove the equivalence to os.ErrNotExist,
+					// and make the message more concise while we're at it.
+					err = fmt.Errorf("replacement directory %s does not exist", r.Path)
+				} else {
+					err = fmt.Errorf("replacement directory %s: %w", r.Path, err)
+				}
+				return dir, true, module.VersionError(mod, err)
+			}
+			return dir, true, nil
+		}
+		mod = r
+	}
+
+	dir, err = modfetch.Download(mod)
+	return dir, false, err
+}
diff --git a/libgo/go/cmd/go/internal/modload/query.go b/libgo/go/cmd/go/internal/modload/query.go
index 031e459..acc886b 100644
--- a/libgo/go/cmd/go/internal/modload/query.go
+++ b/libgo/go/cmd/go/internal/modload/query.go
@@ -381,7 +381,8 @@
 // module and only the version "latest", without checking for other possible
 // modules.
 func QueryPackage(path, query string, allowed func(module.Version) bool) ([]QueryResult, error) {
-	if search.IsMetaPackage(path) || strings.Contains(path, "...") {
+	m := search.NewMatch(path)
+	if m.IsLocal() || !m.IsLiteral() {
 		return nil, fmt.Errorf("pattern %s is not an importable package", path)
 	}
 	return QueryPattern(path, query, allowed)
@@ -402,30 +403,42 @@
 // possible modules.
 func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]QueryResult, error) {
 	base := pattern
-	var match func(m module.Version, root string, isLocal bool) (pkgs []string)
+
+	firstError := func(m *search.Match) error {
+		if len(m.Errs) == 0 {
+			return nil
+		}
+		return m.Errs[0]
+	}
+
+	var match func(mod module.Version, root string, isLocal bool) *search.Match
 
 	if i := strings.Index(pattern, "..."); i >= 0 {
 		base = pathpkg.Dir(pattern[:i+3])
-		match = func(m module.Version, root string, isLocal bool) []string {
-			return matchPackages(pattern, imports.AnyTags(), false, []module.Version{m})
+		match = func(mod module.Version, root string, isLocal bool) *search.Match {
+			m := search.NewMatch(pattern)
+			matchPackages(m, imports.AnyTags(), omitStd, []module.Version{mod})
+			return m
 		}
 	} else {
-		match = func(m module.Version, root string, isLocal bool) []string {
-			prefix := m.Path
-			if m == Target {
+		match = func(mod module.Version, root string, isLocal bool) *search.Match {
+			m := search.NewMatch(pattern)
+			prefix := mod.Path
+			if mod == Target {
 				prefix = targetPrefix
 			}
-			if _, ok := dirInModule(pattern, prefix, root, isLocal); ok {
-				return []string{pattern}
-			} else {
-				return nil
+			if _, ok, err := dirInModule(pattern, prefix, root, isLocal); err != nil {
+				m.AddError(err)
+			} else if ok {
+				m.Pkgs = []string{pattern}
 			}
+			return m
 		}
 	}
 
 	if HasModRoot() {
-		pkgs := match(Target, modRoot, true)
-		if len(pkgs) > 0 {
+		m := match(Target, modRoot, true)
+		if len(m.Pkgs) > 0 {
 			if query != "latest" {
 				return nil, fmt.Errorf("can't query specific version for package %s in the main module (%s)", pattern, Target.Path)
 			}
@@ -435,9 +448,12 @@
 			return []QueryResult{{
 				Mod:      Target,
 				Rev:      &modfetch.RevInfo{Version: Target.Version},
-				Packages: pkgs,
+				Packages: m.Pkgs,
 			}}, nil
 		}
+		if err := firstError(m); err != nil {
+			return nil, err
+		}
 	}
 
 	var (
@@ -445,13 +461,18 @@
 		candidateModules = modulePrefixesExcludingTarget(base)
 	)
 	if len(candidateModules) == 0 {
-		return nil, fmt.Errorf("package %s is not in the main module (%s)", pattern, Target.Path)
+		return nil, &PackageNotInModuleError{
+			Mod:     Target,
+			Query:   query,
+			Pattern: pattern,
+		}
 	}
 
 	err := modfetch.TryProxies(func(proxy string) error {
 		queryModule := func(path string) (r QueryResult, err error) {
+			current := findCurrentVersion(path)
 			r.Mod.Path = path
-			r.Rev, err = queryProxy(proxy, path, query, "", allowed)
+			r.Rev, err = queryProxy(proxy, path, query, current, allowed)
 			if err != nil {
 				return r, err
 			}
@@ -460,8 +481,12 @@
 			if err != nil {
 				return r, err
 			}
-			r.Packages = match(r.Mod, root, isLocal)
+			m := match(r.Mod, root, isLocal)
+			r.Packages = m.Pkgs
 			if len(r.Packages) == 0 {
+				if err := firstError(m); err != nil {
+					return r, err
+				}
 				return r, &PackageNotInModuleError{
 					Mod:         r.Mod,
 					Replacement: Replacement(r.Mod),
@@ -503,6 +528,15 @@
 	return prefixes
 }
 
+func findCurrentVersion(path string) string {
+	for _, m := range buildList {
+		if m.Path == path {
+			return m.Version
+		}
+	}
+	return ""
+}
+
 type prefixResult struct {
 	QueryResult
 	err error
@@ -541,7 +575,9 @@
 		case nil:
 			found = append(found, r.QueryResult)
 		case *PackageNotInModuleError:
-			if noPackage == nil {
+			// Given the option, prefer to attribute “package not in module”
+			// to modules other than the main one.
+			if noPackage == nil || noPackage.Mod == Target {
 				noPackage = rErr
 			}
 		case *NoMatchingVersionError:
@@ -626,6 +662,13 @@
 }
 
 func (e *PackageNotInModuleError) Error() string {
+	if e.Mod == Target {
+		if strings.Contains(e.Pattern, "...") {
+			return fmt.Sprintf("main module (%s) does not contain packages matching %s", Target.Path, e.Pattern)
+		}
+		return fmt.Sprintf("main module (%s) does not contain package %s", Target.Path, e.Pattern)
+	}
+
 	found := ""
 	if r := e.Replacement; r.Path != "" {
 		replacement := r.Path
@@ -647,14 +690,21 @@
 	return fmt.Sprintf("module %s@%s found%s, but does not contain package %s", e.Mod.Path, e.Query, found, e.Pattern)
 }
 
+func (e *PackageNotInModuleError) ImportPath() string {
+	if !strings.Contains(e.Pattern, "...") {
+		return e.Pattern
+	}
+	return ""
+}
+
 // ModuleHasRootPackage returns whether module m contains a package m.Path.
 func ModuleHasRootPackage(m module.Version) (bool, error) {
 	root, isLocal, err := fetch(m)
 	if err != nil {
 		return false, err
 	}
-	_, ok := dirInModule(m.Path, m.Path, root, isLocal)
-	return ok, nil
+	_, ok, err := dirInModule(m.Path, m.Path, root, isLocal)
+	return ok, err
 }
 
 func versionHasGoMod(m module.Version) (bool, error) {
diff --git a/libgo/go/cmd/go/internal/modload/query_test.go b/libgo/go/cmd/go/internal/modload/query_test.go
index 15470e2..247e4c4 100644
--- a/libgo/go/cmd/go/internal/modload/query_test.go
+++ b/libgo/go/cmd/go/internal/modload/query_test.go
@@ -15,8 +15,6 @@
 	"testing"
 
 	"cmd/go/internal/cfg"
-	"cmd/go/internal/modfetch"
-	"cmd/go/internal/modfetch/codehost"
 
 	"golang.org/x/mod/module"
 )
@@ -36,8 +34,7 @@
 
 	os.Setenv("GOPATH", dir)
 	cfg.BuildContext.GOPATH = dir
-	modfetch.PkgMod = filepath.Join(dir, "pkg/mod")
-	codehost.WorkRoot = filepath.Join(dir, "codework")
+	cfg.GOMODCACHE = filepath.Join(dir, "pkg/mod")
 	return m.Run()
 }
 
diff --git a/libgo/go/cmd/go/internal/modload/search.go b/libgo/go/cmd/go/internal/modload/search.go
index a303f51..146c94a 100644
--- a/libgo/go/cmd/go/internal/modload/search.go
+++ b/libgo/go/cmd/go/internal/modload/search.go
@@ -8,9 +8,9 @@
 	"fmt"
 	"os"
 	"path/filepath"
+	"runtime"
 	"strings"
 
-	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/imports"
 	"cmd/go/internal/search"
@@ -18,14 +18,24 @@
 	"golang.org/x/mod/module"
 )
 
-// matchPackages returns a list of packages in the list of modules
-// matching the pattern. Package loading assumes the given set of tags.
-func matchPackages(pattern string, tags map[string]bool, useStd bool, modules []module.Version) []string {
-	match := func(string) bool { return true }
+type stdFilter int8
+
+const (
+	omitStd = stdFilter(iota)
+	includeStd
+)
+
+// matchPackages is like m.MatchPackages, but uses a local variable (rather than
+// a global) for tags, can include or exclude packages in the standard library,
+// and is restricted to the given list of modules.
+func matchPackages(m *search.Match, tags map[string]bool, filter stdFilter, modules []module.Version) {
+	m.Pkgs = []string{}
+
+	isMatch := func(string) bool { return true }
 	treeCanMatch := func(string) bool { return true }
-	if !search.IsMetaPackage(pattern) {
-		match = search.MatchPattern(pattern)
-		treeCanMatch = search.TreeCanMatchPattern(pattern)
+	if !m.IsMeta() {
+		isMatch = search.MatchPattern(m.Pattern())
+		treeCanMatch = search.TreeCanMatchPattern(m.Pattern())
 	}
 
 	have := map[string]bool{
@@ -34,7 +44,6 @@
 	if !cfg.BuildContext.CgoEnabled {
 		have["runtime/cgo"] = true // ignore during walk
 	}
-	var pkgs []string
 
 	type pruning int8
 	const (
@@ -44,8 +53,9 @@
 
 	walkPkgs := func(root, importPathRoot string, prune pruning) {
 		root = filepath.Clean(root)
-		filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
+		err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
 			if err != nil {
+				m.AddError(err)
 				return nil
 			}
 
@@ -94,9 +104,9 @@
 
 			if !have[name] {
 				have[name] = true
-				if match(name) {
+				if isMatch(name) {
 					if _, _, err := scanDir(path, tags); err != imports.ErrNoGo {
-						pkgs = append(pkgs, name)
+						m.Pkgs = append(m.Pkgs, name)
 					}
 				}
 			}
@@ -106,9 +116,12 @@
 			}
 			return nil
 		})
+		if err != nil {
+			m.AddError(err)
+		}
 	}
 
-	if useStd {
+	if filter == includeStd && runtime.Compiler != "gccgo" {
 		walkPkgs(cfg.GOROOTsrc, "", pruneGoMod)
 		if treeCanMatch("cmd") {
 			walkPkgs(filepath.Join(cfg.GOROOTsrc, "cmd"), "cmd", pruneGoMod)
@@ -120,7 +133,7 @@
 			walkPkgs(ModRoot(), targetPrefix, pruneGoMod|pruneVendor)
 			walkPkgs(filepath.Join(ModRoot(), "vendor"), "", pruneVendor)
 		}
-		return pkgs
+		return
 	}
 
 	for _, mod := range modules {
@@ -143,7 +156,7 @@
 			var err error
 			root, isLocal, err = fetch(mod)
 			if err != nil {
-				base.Errorf("go: %v", err)
+				m.AddError(err)
 				continue
 			}
 			modPrefix = mod.Path
@@ -156,5 +169,5 @@
 		walkPkgs(root, modPrefix, prune)
 	}
 
-	return pkgs
+	return
 }
diff --git a/libgo/go/cmd/go/internal/modload/vendor.go b/libgo/go/cmd/go/internal/modload/vendor.go
new file mode 100644
index 0000000..71f68ef
--- /dev/null
+++ b/libgo/go/cmd/go/internal/modload/vendor.go
@@ -0,0 +1,217 @@
+// 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.
+
+package modload
+
+import (
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+	"sync"
+
+	"cmd/go/internal/base"
+
+	"golang.org/x/mod/module"
+	"golang.org/x/mod/semver"
+)
+
+var (
+	vendorOnce      sync.Once
+	vendorList      []module.Version          // modules that contribute packages to the build, in order of appearance
+	vendorReplaced  []module.Version          // all replaced modules; may or may not also contribute packages
+	vendorVersion   map[string]string         // module path → selected version (if known)
+	vendorPkgModule map[string]module.Version // package → containing module
+	vendorMeta      map[module.Version]vendorMetadata
+)
+
+type vendorMetadata struct {
+	Explicit    bool
+	Replacement module.Version
+}
+
+// readVendorList reads the list of vendored modules from vendor/modules.txt.
+func readVendorList() {
+	vendorOnce.Do(func() {
+		vendorList = nil
+		vendorPkgModule = make(map[string]module.Version)
+		vendorVersion = make(map[string]string)
+		vendorMeta = make(map[module.Version]vendorMetadata)
+		data, err := ioutil.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt"))
+		if err != nil {
+			if !errors.Is(err, os.ErrNotExist) {
+				base.Fatalf("go: %s", err)
+			}
+			return
+		}
+
+		var mod module.Version
+		for _, line := range strings.Split(string(data), "\n") {
+			if strings.HasPrefix(line, "# ") {
+				f := strings.Fields(line)
+
+				if len(f) < 3 {
+					continue
+				}
+				if semver.IsValid(f[2]) {
+					// A module, but we don't yet know whether it is in the build list or
+					// only included to indicate a replacement.
+					mod = module.Version{Path: f[1], Version: f[2]}
+					f = f[3:]
+				} else if f[2] == "=>" {
+					// A wildcard replacement found in the main module's go.mod file.
+					mod = module.Version{Path: f[1]}
+					f = f[2:]
+				} else {
+					// Not a version or a wildcard replacement.
+					// We don't know how to interpret this module line, so ignore it.
+					mod = module.Version{}
+					continue
+				}
+
+				if len(f) >= 2 && f[0] == "=>" {
+					meta := vendorMeta[mod]
+					if len(f) == 2 {
+						// File replacement.
+						meta.Replacement = module.Version{Path: f[1]}
+						vendorReplaced = append(vendorReplaced, mod)
+					} else if len(f) == 3 && semver.IsValid(f[2]) {
+						// Path and version replacement.
+						meta.Replacement = module.Version{Path: f[1], Version: f[2]}
+						vendorReplaced = append(vendorReplaced, mod)
+					} else {
+						// We don't understand this replacement. Ignore it.
+					}
+					vendorMeta[mod] = meta
+				}
+				continue
+			}
+
+			// Not a module line. Must be a package within a module or a metadata
+			// directive, either of which requires a preceding module line.
+			if mod.Path == "" {
+				continue
+			}
+
+			if strings.HasPrefix(line, "## ") {
+				// Metadata. Take the union of annotations across multiple lines, if present.
+				meta := vendorMeta[mod]
+				for _, entry := range strings.Split(strings.TrimPrefix(line, "## "), ";") {
+					entry = strings.TrimSpace(entry)
+					if entry == "explicit" {
+						meta.Explicit = true
+					}
+					// All other tokens are reserved for future use.
+				}
+				vendorMeta[mod] = meta
+				continue
+			}
+
+			if f := strings.Fields(line); len(f) == 1 && module.CheckImportPath(f[0]) == nil {
+				// A package within the current module.
+				vendorPkgModule[f[0]] = mod
+
+				// Since this module provides a package for the build, we know that it
+				// is in the build list and is the selected version of its path.
+				// If this information is new, record it.
+				if v, ok := vendorVersion[mod.Path]; !ok || semver.Compare(v, mod.Version) < 0 {
+					vendorList = append(vendorList, mod)
+					vendorVersion[mod.Path] = mod.Version
+				}
+			}
+		}
+	})
+}
+
+// checkVendorConsistency verifies that the vendor/modules.txt file matches (if
+// go 1.14) or at least does not contradict (go 1.13 or earlier) the
+// requirements and replacements listed in the main module's go.mod file.
+func checkVendorConsistency() {
+	readVendorList()
+
+	pre114 := false
+	if modFile.Go == nil || semver.Compare("v"+modFile.Go.Version, "v1.14") < 0 {
+		// Go versions before 1.14 did not include enough information in
+		// vendor/modules.txt to check for consistency.
+		// If we know that we're on an earlier version, relax the consistency check.
+		pre114 = true
+	}
+
+	vendErrors := new(strings.Builder)
+	vendErrorf := func(mod module.Version, format string, args ...interface{}) {
+		detail := fmt.Sprintf(format, args...)
+		if mod.Version == "" {
+			fmt.Fprintf(vendErrors, "\n\t%s: %s", mod.Path, detail)
+		} else {
+			fmt.Fprintf(vendErrors, "\n\t%s@%s: %s", mod.Path, mod.Version, detail)
+		}
+	}
+
+	for _, r := range modFile.Require {
+		if !vendorMeta[r.Mod].Explicit {
+			if pre114 {
+				// Before 1.14, modules.txt did not indicate whether modules were listed
+				// explicitly in the main module's go.mod file.
+				// However, we can at least detect a version mismatch if packages were
+				// vendored from a non-matching version.
+				if vv, ok := vendorVersion[r.Mod.Path]; ok && vv != r.Mod.Version {
+					vendErrorf(r.Mod, fmt.Sprintf("is explicitly required in go.mod, but vendor/modules.txt indicates %s@%s", r.Mod.Path, vv))
+				}
+			} else {
+				vendErrorf(r.Mod, "is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt")
+			}
+		}
+	}
+
+	describe := func(m module.Version) string {
+		if m.Version == "" {
+			return m.Path
+		}
+		return m.Path + "@" + m.Version
+	}
+
+	// We need to verify *all* replacements that occur in modfile: even if they
+	// don't directly apply to any module in the vendor list, the replacement
+	// go.mod file can affect the selected versions of other (transitive)
+	// dependencies
+	for _, r := range modFile.Replace {
+		vr := vendorMeta[r.Old].Replacement
+		if vr == (module.Version{}) {
+			if pre114 && (r.Old.Version == "" || vendorVersion[r.Old.Path] != r.Old.Version) {
+				// Before 1.14, modules.txt omitted wildcard replacements and
+				// replacements for modules that did not have any packages to vendor.
+			} else {
+				vendErrorf(r.Old, "is replaced in go.mod, but not marked as replaced in vendor/modules.txt")
+			}
+		} else if vr != r.New {
+			vendErrorf(r.Old, "is replaced by %s in go.mod, but marked as replaced by %s in vendor/modules.txt", describe(r.New), describe(vr))
+		}
+	}
+
+	for _, mod := range vendorList {
+		meta := vendorMeta[mod]
+		if meta.Explicit {
+			if _, inGoMod := index.require[mod]; !inGoMod {
+				vendErrorf(mod, "is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod")
+			}
+		}
+	}
+
+	for _, mod := range vendorReplaced {
+		r := Replacement(mod)
+		if r == (module.Version{}) {
+			vendErrorf(mod, "is marked as replaced in vendor/modules.txt, but not replaced in go.mod")
+			continue
+		}
+		if meta := vendorMeta[mod]; r != meta.Replacement {
+			vendErrorf(mod, "is marked as replaced by %s in vendor/modules.txt, but replaced by %s in go.mod", describe(meta.Replacement), describe(r))
+		}
+	}
+
+	if vendErrors.Len() > 0 {
+		base.Fatalf("go: inconsistent vendoring in %s:%s\n\nrun 'go mod vendor' to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory", modRoot, vendErrors)
+	}
+}
diff --git a/libgo/go/cmd/go/internal/mvs/mvs.go b/libgo/go/cmd/go/internal/mvs/mvs.go
index dd3b3cc..1f8eaa1 100644
--- a/libgo/go/cmd/go/internal/mvs/mvs.go
+++ b/libgo/go/cmd/go/internal/mvs/mvs.go
@@ -115,7 +115,21 @@
 }
 
 // BuildList returns the build list for the target module.
-// The first element is the target itself, with the remainder of the list sorted by path.
+//
+// target is the root vertex of a module requirement graph. For cmd/go, this is
+// typically the main module, but note that this algorithm is not intended to
+// be Go-specific: module paths and versions are treated as opaque values.
+//
+// reqs describes the module requirement graph and provides an opaque method
+// for comparing versions.
+//
+// BuildList traverses the graph and returns a list containing the highest
+// version for each visited module. The first element of the returned list is
+// target itself; reqs.Max requires target.Version to compare higher than all
+// other versions, so no other version can be selected. The remaining elements
+// of the list are sorted by path.
+//
+// See https://research.swtch.com/vgo-mvs for details.
 func BuildList(target module.Version, reqs Reqs) ([]module.Version, error) {
 	return buildList(target, reqs, nil)
 }
@@ -220,10 +234,9 @@
 	// The final list is the minimum version of each module found in the graph.
 
 	if v := min[target.Path]; v != target.Version {
-		// TODO(jayconrod): there is a special case in modload.mvsReqs.Max
-		// that prevents us from selecting a newer version of a module
-		// when the module has no version. This may only be the case for target.
-		// Should we always panic when target has a version?
+		// target.Version will be "" for modload, the main client of MVS.
+		// "" denotes the main module, which has no version. However, MVS treats
+		// version strings as opaque, so "" is not a special value here.
 		// See golang.org/issue/31491, golang.org/issue/29773.
 		panic(fmt.Sprintf("mistake: chose version %q instead of target %+v", v, target)) // TODO: Don't panic.
 	}
diff --git a/libgo/go/cmd/go/internal/renameio/renameio_test.go b/libgo/go/cmd/go/internal/renameio/renameio_test.go
index ee2f3ba..df8ddab 100644
--- a/libgo/go/cmd/go/internal/renameio/renameio_test.go
+++ b/libgo/go/cmd/go/internal/renameio/renameio_test.go
@@ -9,11 +9,13 @@
 import (
 	"encoding/binary"
 	"errors"
+	"internal/testenv"
 	"io/ioutil"
 	"math/rand"
 	"os"
 	"path/filepath"
 	"runtime"
+	"strings"
 	"sync"
 	"sync/atomic"
 	"syscall"
@@ -24,6 +26,10 @@
 )
 
 func TestConcurrentReadsAndWrites(t *testing.T) {
+	if runtime.GOOS == "darwin" && strings.HasSuffix(testenv.Builder(), "-10_14") {
+		testenv.SkipFlaky(t, 33041)
+	}
+
 	dir, err := ioutil.TempDir("", "renameio")
 	if err != nil {
 		t.Fatal(err)
diff --git a/libgo/go/cmd/go/internal/search/search.go b/libgo/go/cmd/go/internal/search/search.go
index ad33e60..4efef24 100644
--- a/libgo/go/cmd/go/internal/search/search.go
+++ b/libgo/go/cmd/go/internal/search/search.go
@@ -9,7 +9,6 @@
 	"cmd/go/internal/cfg"
 	"fmt"
 	"go/build"
-	"log"
 	"os"
 	"path"
 	"path/filepath"
@@ -19,25 +18,97 @@
 
 // A Match represents the result of matching a single package pattern.
 type Match struct {
-	Pattern string   // the pattern itself
-	Literal bool     // whether it is a literal (no wildcards)
-	Pkgs    []string // matching packages (dirs or import paths)
+	pattern string   // the pattern itself
+	Dirs    []string // if the pattern is local, directories that potentially contain matching packages
+	Pkgs    []string // matching packages (import paths)
+	Errs    []error  // errors matching the patterns to packages, NOT errors loading those packages
+
+	// Errs may be non-empty even if len(Pkgs) > 0, indicating that some matching
+	// packages could be located but results may be incomplete.
+	// If len(Pkgs) == 0 && len(Errs) == 0, the pattern is well-formed but did not
+	// match any packages.
 }
 
-// MatchPackages returns all the packages that can be found
-// under the $GOPATH directories and $GOROOT matching pattern.
-// The pattern is either "all" (all packages), "std" (standard packages),
-// "cmd" (standard commands), or a path including "...".
-func MatchPackages(pattern string) *Match {
-	m := &Match{
-		Pattern: pattern,
-		Literal: false,
+// NewMatch returns a Match describing the given pattern,
+// without resolving its packages or errors.
+func NewMatch(pattern string) *Match {
+	return &Match{pattern: pattern}
+}
+
+// Pattern returns the pattern to be matched.
+func (m *Match) Pattern() string { return m.pattern }
+
+// AddError appends a MatchError wrapping err to m.Errs.
+func (m *Match) AddError(err error) {
+	m.Errs = append(m.Errs, &MatchError{Match: m, Err: err})
+}
+
+// Literal reports whether the pattern is free of wildcards and meta-patterns.
+//
+// A literal pattern must match at most one package.
+func (m *Match) IsLiteral() bool {
+	return !strings.Contains(m.pattern, "...") && !m.IsMeta()
+}
+
+// Local reports whether the pattern must be resolved from a specific root or
+// directory, such as a filesystem path or a single module.
+func (m *Match) IsLocal() bool {
+	return build.IsLocalImport(m.pattern) || filepath.IsAbs(m.pattern)
+}
+
+// Meta reports whether the pattern is a “meta-package” keyword that represents
+// multiple packages, such as "std", "cmd", or "all".
+func (m *Match) IsMeta() bool {
+	return IsMetaPackage(m.pattern)
+}
+
+// IsMetaPackage checks if name is a reserved package name that expands to multiple packages.
+func IsMetaPackage(name string) bool {
+	return name == "std" || name == "cmd" || name == "all"
+}
+
+// A MatchError indicates an error that occurred while attempting to match a
+// pattern.
+type MatchError struct {
+	Match *Match
+	Err   error
+}
+
+func (e *MatchError) Error() string {
+	if e.Match.IsLiteral() {
+		return fmt.Sprintf("%s: %v", e.Match.Pattern(), e.Err)
 	}
+	return fmt.Sprintf("pattern %s: %v", e.Match.Pattern(), e.Err)
+}
+
+func (e *MatchError) Unwrap() error {
+	return e.Err
+}
+
+// MatchPackages sets m.Pkgs to a non-nil slice containing all the packages that
+// can be found under the $GOPATH directories and $GOROOT that match the
+// pattern. The pattern must be either "all" (all packages), "std" (standard
+// packages), "cmd" (standard commands), or a path including "...".
+//
+// If any errors may have caused the set of packages to be incomplete,
+// MatchPackages appends those errors to m.Errs.
+func (m *Match) MatchPackages() {
+	m.Pkgs = []string{}
+	if m.IsLocal() {
+		m.AddError(fmt.Errorf("internal error: MatchPackages: %s is not a valid package pattern", m.pattern))
+		return
+	}
+
+	if m.IsLiteral() {
+		m.Pkgs = []string{m.pattern}
+		return
+	}
+
 	match := func(string) bool { return true }
 	treeCanMatch := func(string) bool { return true }
-	if !IsMetaPackage(pattern) {
-		match = MatchPattern(pattern)
-		treeCanMatch = TreeCanMatchPattern(pattern)
+	if !m.IsMeta() {
+		match = MatchPattern(m.pattern)
+		treeCanMatch = TreeCanMatchPattern(m.pattern)
 	}
 
 	have := map[string]bool{
@@ -48,17 +119,20 @@
 	}
 
 	for _, src := range cfg.BuildContext.SrcDirs() {
-		if (pattern == "std" || pattern == "cmd") && src != cfg.GOROOTsrc {
+		if (m.pattern == "std" || m.pattern == "cmd") && src != cfg.GOROOTsrc {
 			continue
 		}
 		src = filepath.Clean(src) + string(filepath.Separator)
 		root := src
-		if pattern == "cmd" {
+		if m.pattern == "cmd" {
 			root += "cmd" + string(filepath.Separator)
 		}
-		filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
-			if err != nil || path == src {
-				return nil
+		err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
+			if err != nil {
+				return err // Likely a permission error, which could interfere with matching.
+			}
+			if path == src {
+				return nil // GOROOT/src and GOPATH/src cannot contain packages.
 			}
 
 			want := true
@@ -69,7 +143,7 @@
 			}
 
 			name := filepath.ToSlash(path[len(src):])
-			if pattern == "std" && (!IsStandardImportPath(name) || name == "cmd") {
+			if m.pattern == "std" && (!IsStandardImportPath(name) || name == "cmd") {
 				// The name "std" is only the standard library.
 				// If the name is cmd, it's the root of the command tree.
 				want = false
@@ -100,23 +174,30 @@
 			pkg, err := cfg.BuildContext.ImportDir(path, 0)
 			if err != nil {
 				if _, noGo := err.(*build.NoGoError); noGo {
+					// The package does not actually exist, so record neither the package
+					// nor the error.
 					return nil
 				}
+				// There was an error importing path, but not matching it,
+				// which is all that Match promises to do.
+				// Ignore the import error.
 			}
 
 			// If we are expanding "cmd", skip main
 			// packages under cmd/vendor. At least as of
 			// March, 2017, there is one there for the
 			// vendored pprof tool.
-			if pattern == "cmd" && strings.HasPrefix(pkg.ImportPath, "cmd/vendor") && pkg.Name == "main" {
+			if m.pattern == "cmd" && pkg != nil && strings.HasPrefix(pkg.ImportPath, "cmd/vendor") && pkg.Name == "main" {
 				return nil
 			}
 
 			m.Pkgs = append(m.Pkgs, name)
 			return nil
 		})
+		if err != nil {
+			m.AddError(err)
+		}
 	}
-	return m
 }
 
 var modRoot string
@@ -125,24 +206,31 @@
 	modRoot = dir
 }
 
-// MatchPackagesInFS is like MatchPackages but is passed a pattern that
-// begins with an absolute path or "./" or "../". On Windows, the pattern may
-// use slash or backslash separators or a mix of both.
+// MatchDirs sets m.Dirs to a non-nil slice containing all directories that
+// potentially match a local pattern. The pattern must begin with an absolute
+// path, or "./", or "../". On Windows, the pattern may use slash or backslash
+// separators or a mix of both.
 //
-// MatchPackagesInFS scans the tree rooted at the directory that contains the
-// first "..." wildcard and returns a match with packages that
-func MatchPackagesInFS(pattern string) *Match {
-	m := &Match{
-		Pattern: pattern,
-		Literal: false,
+// If any errors may have caused the set of directories to be incomplete,
+// MatchDirs appends those errors to m.Errs.
+func (m *Match) MatchDirs() {
+	m.Dirs = []string{}
+	if !m.IsLocal() {
+		m.AddError(fmt.Errorf("internal error: MatchDirs: %s is not a valid filesystem pattern", m.pattern))
+		return
+	}
+
+	if m.IsLiteral() {
+		m.Dirs = []string{m.pattern}
+		return
 	}
 
 	// Clean the path and create a matching predicate.
 	// filepath.Clean removes "./" prefixes (and ".\" on Windows). We need to
 	// preserve these, since they are meaningful in MatchPattern and in
 	// returned import paths.
-	cleanPattern := filepath.Clean(pattern)
-	isLocal := strings.HasPrefix(pattern, "./") || (os.PathSeparator == '\\' && strings.HasPrefix(pattern, `.\`))
+	cleanPattern := filepath.Clean(m.pattern)
+	isLocal := strings.HasPrefix(m.pattern, "./") || (os.PathSeparator == '\\' && strings.HasPrefix(m.pattern, `.\`))
 	prefix := ""
 	if cleanPattern != "." && isLocal {
 		prefix = "./"
@@ -166,16 +254,20 @@
 	if modRoot != "" {
 		abs, err := filepath.Abs(dir)
 		if err != nil {
-			base.Fatalf("go: %v", err)
+			m.AddError(err)
+			return
 		}
 		if !hasFilepathPrefix(abs, modRoot) {
-			base.Fatalf("go: pattern %s refers to dir %s, outside module root %s", pattern, abs, modRoot)
-			return nil
+			m.AddError(fmt.Errorf("directory %s is outside module root (%s)", abs, modRoot))
+			return
 		}
 	}
 
-	filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
-		if err != nil || !fi.IsDir() {
+	err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
+		if err != nil {
+			return err // Likely a permission error, which could interfere with matching.
+		}
+		if !fi.IsDir() {
 			return nil
 		}
 		top := false
@@ -218,15 +310,21 @@
 		// behavior means people miss serious mistakes.
 		// See golang.org/issue/11407.
 		if p, err := cfg.BuildContext.ImportDir(path, 0); err != nil && (p == nil || len(p.InvalidGoFiles) == 0) {
-			if _, noGo := err.(*build.NoGoError); !noGo {
-				log.Print(err)
+			if _, noGo := err.(*build.NoGoError); noGo {
+				// The package does not actually exist, so record neither the package
+				// nor the error.
+				return nil
 			}
-			return nil
+			// There was an error importing path, but not matching it,
+			// which is all that Match promises to do.
+			// Ignore the import error.
 		}
-		m.Pkgs = append(m.Pkgs, name)
+		m.Dirs = append(m.Dirs, name)
 		return nil
 	})
-	return m
+	if err != nil {
+		m.AddError(err)
+	}
 }
 
 // TreeCanMatchPattern(pattern)(name) reports whether
@@ -316,8 +414,8 @@
 // WarnUnmatched warns about patterns that didn't match any packages.
 func WarnUnmatched(matches []*Match) {
 	for _, m := range matches {
-		if len(m.Pkgs) == 0 {
-			fmt.Fprintf(os.Stderr, "go: warning: %q matched no packages\n", m.Pattern)
+		if len(m.Pkgs) == 0 && len(m.Errs) == 0 {
+			fmt.Fprintf(os.Stderr, "go: warning: %q matched no packages\n", m.pattern)
 		}
 	}
 }
@@ -334,40 +432,30 @@
 func ImportPathsQuiet(patterns []string) []*Match {
 	var out []*Match
 	for _, a := range CleanPatterns(patterns) {
-		if IsMetaPackage(a) {
-			out = append(out, MatchPackages(a))
-			continue
-		}
-
-		if build.IsLocalImport(a) || filepath.IsAbs(a) {
-			var m *Match
-			if strings.Contains(a, "...") {
-				m = MatchPackagesInFS(a)
-			} else {
-				m = &Match{Pattern: a, Literal: true, Pkgs: []string{a}}
-			}
+		m := NewMatch(a)
+		if m.IsLocal() {
+			m.MatchDirs()
 
 			// Change the file import path to a regular import path if the package
 			// is in GOPATH or GOROOT. We don't report errors here; LoadImport
 			// (or something similar) will report them later.
-			for i, dir := range m.Pkgs {
+			m.Pkgs = make([]string, len(m.Dirs))
+			for i, dir := range m.Dirs {
+				absDir := dir
 				if !filepath.IsAbs(dir) {
-					dir = filepath.Join(base.Cwd, dir)
+					absDir = filepath.Join(base.Cwd, dir)
 				}
-				if bp, _ := cfg.BuildContext.ImportDir(dir, build.FindOnly); bp.ImportPath != "" && bp.ImportPath != "." {
+				if bp, _ := cfg.BuildContext.ImportDir(absDir, build.FindOnly); bp.ImportPath != "" && bp.ImportPath != "." {
 					m.Pkgs[i] = bp.ImportPath
+				} else {
+					m.Pkgs[i] = dir
 				}
 			}
-			out = append(out, m)
-			continue
+		} else {
+			m.MatchPackages()
 		}
 
-		if strings.Contains(a, "...") {
-			out = append(out, MatchPackages(a))
-			continue
-		}
-
-		out = append(out, &Match{Pattern: a, Literal: true, Pkgs: []string{a}})
+		out = append(out, m)
 	}
 	return out
 }
@@ -419,11 +507,6 @@
 	return out
 }
 
-// IsMetaPackage checks if name is a reserved package name that expands to multiple packages.
-func IsMetaPackage(name string) bool {
-	return name == "std" || name == "cmd" || name == "all"
-}
-
 // hasPathPrefix reports whether the path s begins with the
 // elements in prefix.
 func hasPathPrefix(s, prefix string) bool {
diff --git a/libgo/go/cmd/go/internal/str/path.go b/libgo/go/cmd/go/internal/str/path.go
index a4ffc5f..95d91a3 100644
--- a/libgo/go/cmd/go/internal/str/path.go
+++ b/libgo/go/cmd/go/internal/str/path.go
@@ -10,7 +10,7 @@
 	"strings"
 )
 
-// HasPath reports whether the slash-separated path s
+// HasPathPrefix reports whether the slash-separated path s
 // begins with the elements in prefix.
 func HasPathPrefix(s, prefix string) bool {
 	if len(s) == len(prefix) {
diff --git a/libgo/go/cmd/go/internal/test/flagdefs.go b/libgo/go/cmd/go/internal/test/flagdefs.go
new file mode 100644
index 0000000..8a0a076
--- /dev/null
+++ b/libgo/go/cmd/go/internal/test/flagdefs.go
@@ -0,0 +1,34 @@
+// 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.
+
+// Code generated by genflags.go — DO NOT EDIT.
+
+package test
+
+// passFlagToTest contains the flags that should be forwarded to
+// the test binary with the prefix "test.".
+var passFlagToTest = map[string]bool{
+	"bench":                true,
+	"benchmem":             true,
+	"benchtime":            true,
+	"blockprofile":         true,
+	"blockprofilerate":     true,
+	"count":                true,
+	"coverprofile":         true,
+	"cpu":                  true,
+	"cpuprofile":           true,
+	"failfast":             true,
+	"list":                 true,
+	"memprofile":           true,
+	"memprofilerate":       true,
+	"mutexprofile":         true,
+	"mutexprofilefraction": true,
+	"outputdir":            true,
+	"parallel":             true,
+	"run":                  true,
+	"short":                true,
+	"timeout":              true,
+	"trace":                true,
+	"v":                    true,
+}
diff --git a/libgo/go/cmd/go/internal/test/flagdefs_test.go b/libgo/go/cmd/go/internal/test/flagdefs_test.go
new file mode 100644
index 0000000..7562415
--- /dev/null
+++ b/libgo/go/cmd/go/internal/test/flagdefs_test.go
@@ -0,0 +1,34 @@
+// 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.
+
+package test
+
+import (
+	"flag"
+	"strings"
+	"testing"
+)
+
+func TestPassFlagToTestIncludesAllTestFlags(t *testing.T) {
+	flag.VisitAll(func(f *flag.Flag) {
+		if !strings.HasPrefix(f.Name, "test.") {
+			return
+		}
+		name := strings.TrimPrefix(f.Name, "test.")
+		if name != "testlogfile" && !passFlagToTest[name] {
+			t.Errorf("passFlagToTest missing entry for %q (flag test.%s)", name, name)
+			t.Logf("(Run 'go generate cmd/go/internal/test' if it should be added.)")
+		}
+	})
+
+	for name := range passFlagToTest {
+		if flag.Lookup("test."+name) == nil {
+			t.Errorf("passFlagToTest contains %q, but flag -test.%s does not exist in test binary", name, name)
+		}
+
+		if CmdTest.Flag.Lookup(name) == nil {
+			t.Errorf("passFlagToTest contains %q, but flag -%s does not exist in 'go test' subcommand", name, name)
+		}
+	}
+}
diff --git a/libgo/go/cmd/go/internal/test/genflags.go b/libgo/go/cmd/go/internal/test/genflags.go
new file mode 100644
index 0000000..512fa16
--- /dev/null
+++ b/libgo/go/cmd/go/internal/test/genflags.go
@@ -0,0 +1,90 @@
+// 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 ignore
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"log"
+	"os"
+	"os/exec"
+	"strings"
+	"testing"
+	"text/template"
+)
+
+func main() {
+	if err := regenerate(); err != nil {
+		log.Fatal(err)
+	}
+}
+
+func regenerate() error {
+	t := template.Must(template.New("fileTemplate").Parse(fileTemplate))
+	buf := bytes.NewBuffer(nil)
+	if err := t.Execute(buf, testFlags()); err != nil {
+		return err
+	}
+
+	f, err := os.Create("flagdefs.go")
+	if err != nil {
+		return err
+	}
+
+	cmd := exec.Command("gofmt")
+	cmd.Stdin = buf
+	cmd.Stdout = f
+	cmd.Stderr = os.Stderr
+	cmdErr := cmd.Run()
+
+	if err := f.Close(); err != nil {
+		return err
+	}
+	if cmdErr != nil {
+		os.Remove(f.Name())
+		return cmdErr
+	}
+
+	return nil
+}
+
+func testFlags() []string {
+	testing.Init()
+
+	var names []string
+	flag.VisitAll(func(f *flag.Flag) {
+		if !strings.HasPrefix(f.Name, "test.") {
+			return
+		}
+		name := strings.TrimPrefix(f.Name, "test.")
+
+		if name == "testlogfile" {
+			// test.testlogfile is “for use only by cmd/go”
+		} else {
+			names = append(names, name)
+		}
+	})
+
+	return names
+}
+
+const fileTemplate = `// 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.
+
+// Code generated by genflags.go — DO NOT EDIT.
+
+package test
+
+// passFlagToTest contains the flags that should be forwarded to
+// the test binary with the prefix "test.".
+var passFlagToTest = map[string]bool {
+{{- range .}}
+	"{{.}}": true,
+{{- end }}
+}
+`
diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go
index 4ad142c..873a76a 100644
--- a/libgo/go/cmd/go/internal/test/test.go
+++ b/libgo/go/cmd/go/internal/test/test.go
@@ -73,10 +73,10 @@
 and its test source files to identify significant problems. If go vet
 finds any problems, go test reports those and does not run the test
 binary. Only a high-confidence subset of the default go vet checks are
-used. That subset is: 'atomic', 'bool', 'buildtags', 'nilfunc', and
-'printf'. You can see the documentation for these and other vet tests
-via "go doc cmd/vet". To disable the running of go vet, use the
--vet=off flag.
+used. That subset is: 'atomic', 'bool', 'buildtags', 'errorsas',
+'ifaceassert', 'nilfunc', 'printf', and 'stringintconv'. You can see
+the documentation for these and other vet tests via "go doc cmd/vet".
+To disable the running of go vet, use the -vet=off flag.
 
 All test output and summary lines are printed to the go command's
 standard output, even if the test printed them to its own standard
@@ -466,37 +466,78 @@
 }
 
 var (
-	testC            bool            // -c flag
-	testCover        bool            // -cover flag
-	testCoverMode    string          // -covermode flag
-	testCoverPaths   []string        // -coverpkg flag
-	testCoverPkgs    []*load.Package // -coverpkg flag
-	testCoverProfile string          // -coverprofile flag
-	testOutputDir    string          // -outputdir flag
-	testO            string          // -o flag
-	testProfile      string          // profiling flag that limits test to one package
-	testNeedBinary   bool            // profile needs to keep binary around
-	testJSON         bool            // -json flag
-	testV            bool            // -v flag
-	testTimeout      string          // -timeout flag
-	testArgs         []string
-	testBench        bool
-	testList         bool
-	testShowPass     bool   // show passing output
-	testVetList      string // -vet flag
-	pkgArgs          []string
-	pkgs             []*load.Package
-
-	testActualTimeout = 10 * time.Minute                  // actual timeout which is passed to tests
-	testKillTimeout   = testActualTimeout + 1*time.Minute // backup alarm
-	testCacheExpire   time.Time                           // ignore cached test results before this time
+	testBench        string                            // -bench flag
+	testC            bool                              // -c flag
+	testCover        bool                              // -cover flag
+	testCoverMode    string                            // -covermode flag
+	testCoverPaths   []string                          // -coverpkg flag
+	testCoverPkgs    []*load.Package                   // -coverpkg flag
+	testCoverProfile string                            // -coverprofile flag
+	testJSON         bool                              // -json flag
+	testList         string                            // -list flag
+	testO            string                            // -o flag
+	testOutputDir    = base.Cwd                        // -outputdir flag
+	testTimeout      time.Duration                     // -timeout flag
+	testV            bool                              // -v flag
+	testVet          = vetFlag{flags: defaultVetFlags} // -vet flag
 )
 
-// testVetExplicit records whether testVetFlags were set by an explicit -vet.
-var testVetExplicit = false
+var (
+	testArgs []string
+	pkgArgs  []string
+	pkgs     []*load.Package
 
-// testVetFlags is the list of flags to pass to vet when invoked automatically during go test.
-var testVetFlags = []string{
+	testHelp bool // -help option passed to test via -args
+
+	testKillTimeout = 100 * 365 * 24 * time.Hour // backup alarm; defaults to about a century if no timeout is set
+	testCacheExpire time.Time                    // ignore cached test results before this time
+
+	testBlockProfile, testCPUProfile, testMemProfile, testMutexProfile, testTrace string // profiling flag that limits test to one package
+)
+
+// testProfile returns the name of an arbitrary single-package profiling flag
+// that is set, if any.
+func testProfile() string {
+	switch {
+	case testBlockProfile != "":
+		return "-blockprofile"
+	case testCPUProfile != "":
+		return "-cpuprofile"
+	case testMemProfile != "":
+		return "-memprofile"
+	case testMutexProfile != "":
+		return "-mutexprofile"
+	case testTrace != "":
+		return "-trace"
+	default:
+		return ""
+	}
+}
+
+// testNeedBinary reports whether the test needs to keep the binary around.
+func testNeedBinary() bool {
+	switch {
+	case testBlockProfile != "":
+		return true
+	case testCPUProfile != "":
+		return true
+	case testMemProfile != "":
+		return true
+	case testMutexProfile != "":
+		return true
+	case testO != "":
+		return true
+	default:
+		return false
+	}
+}
+
+// testShowPass reports whether the output for a passing test should be shown.
+func testShowPass() bool {
+	return testV || (testList != "") || testHelp
+}
+
+var defaultVetFlags = []string{
 	// TODO(rsc): Decide which tests are enabled by default.
 	// See golang.org/issue/18085.
 	// "-asmdecl",
@@ -509,12 +550,14 @@
 	// "-copylocks",
 	"-errorsas",
 	// "-httpresponse",
+	"-ifaceassert",
 	// "-lostcancel",
 	// "-methods",
 	"-nilfunc",
 	"-printf",
 	// "-rangeloops",
 	// "-shift",
+	"-stringintconv",
 	// "-structtags",
 	// "-tests",
 	// "-unreachable",
@@ -522,22 +565,16 @@
 	// "-unusedresult",
 }
 
-func testCmdUsage() {
-	fmt.Fprintf(os.Stderr, "usage: %s\n", CmdTest.UsageLine)
-	fmt.Fprintf(os.Stderr, "Run 'go help %s' and 'go help %s' for details.\n", CmdTest.LongName(), HelpTestflag.LongName())
-	os.Exit(2)
-}
-
 func runTest(cmd *base.Command, args []string) {
 	modload.LoadTests = true
 
-	pkgArgs, testArgs = testFlags(testCmdUsage, args)
+	pkgArgs, testArgs = testFlags(args)
 
 	work.FindExecCmd() // initialize cached result
 
 	work.BuildInit()
-	work.VetFlags = testVetFlags
-	work.VetExplicit = testVetExplicit
+	work.VetFlags = testVet.flags
+	work.VetExplicit = testVet.explicit
 
 	pkgs = load.PackagesForBuild(pkgArgs)
 	if len(pkgs) == 0 {
@@ -550,38 +587,20 @@
 	if testO != "" && len(pkgs) != 1 {
 		base.Fatalf("cannot use -o flag with multiple packages")
 	}
-	if testProfile != "" && len(pkgs) != 1 {
-		base.Fatalf("cannot use %s flag with multiple packages", testProfile)
+	if testProfile() != "" && len(pkgs) != 1 {
+		base.Fatalf("cannot use %s flag with multiple packages", testProfile())
 	}
 	initCoverProfile()
 	defer closeCoverProfile()
 
-	// If a test timeout was given and is parseable, set our kill timeout
+	// If a test timeout is finite, set our kill timeout
 	// to that timeout plus one minute. This is a backup alarm in case
 	// the test wedges with a goroutine spinning and its background
 	// timer does not get a chance to fire.
-	if dt, err := time.ParseDuration(testTimeout); err == nil && dt > 0 {
-		testActualTimeout = dt
-		testKillTimeout = testActualTimeout + 1*time.Minute
-	} else if err == nil && dt == 0 {
-		// An explicit zero disables the test timeout.
-		// No timeout is passed to tests.
-		// Let it have one century (almost) before we kill it.
-		testActualTimeout = -1
-		testKillTimeout = 100 * 365 * 24 * time.Hour
+	if testTimeout > 0 {
+		testKillTimeout = testTimeout + 1*time.Minute
 	}
 
-	// Pass timeout to tests if it exists.
-	// Prepend rather than appending so that it appears before positional arguments.
-	if testActualTimeout > 0 {
-		testArgs = append([]string{"-test.timeout=" + testActualTimeout.String()}, testArgs...)
-	}
-
-	// show passing test output (after buffering) with -v flag.
-	// must buffer because tests are running in parallel, and
-	// otherwise the output will get mixed.
-	testShowPass = testV || testList
-
 	// For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier.
 	if cfg.BuildI && testO != "" {
 		testC = true
@@ -755,7 +774,7 @@
 	}
 
 	// Force benchmarks to run in serial.
-	if !testC && testBench {
+	if !testC && (testBench != "") {
 		// The first run must wait for all builds.
 		// Later runs must wait for the previous run's print.
 		for i, run := range runs {
@@ -839,7 +858,7 @@
 	}
 
 	pmain.Dir = testDir
-	pmain.Internal.OmitDebug = !testC && !testNeedBinary
+	pmain.Internal.OmitDebug = !testC && !testNeedBinary()
 
 	if !cfg.BuildN {
 		// writeTestmain writes _testmain.go,
@@ -887,7 +906,7 @@
 	}
 	buildAction = a
 	var installAction, cleanAction *work.Action
-	if testC || testNeedBinary {
+	if testC || testNeedBinary() {
 		// -c or profiling flag: create action to copy binary to ./test.out.
 		target := filepath.Join(base.Cwd, testBinary+cfg.ExeSuffix)
 		if testO != "" {
@@ -964,7 +983,7 @@
 }
 
 func addTestVet(b *work.Builder, p *load.Package, runAction, installAction *work.Action) {
-	if testVetList == "off" {
+	if testVet.off {
 		return
 	}
 
@@ -1067,7 +1086,7 @@
 	}
 
 	var buf bytes.Buffer
-	if len(pkgArgs) == 0 || testBench {
+	if len(pkgArgs) == 0 || (testBench != "") {
 		// Stream test output (no buffering) when no package has
 		// been given on the command line (implicit current directory)
 		// or when benchmarking.
@@ -1087,7 +1106,7 @@
 		// possible even when multiple tests are being run: the JSON output
 		// events are attributed to specific package tests, so interlacing them
 		// is OK.
-		if testShowPass && (len(pkgs) == 1 || cfg.BuildP == 1) || testJSON {
+		if testShowPass() && (len(pkgs) == 1 || cfg.BuildP == 1) || testJSON {
 			// Write both to stdout and buf, for possible saving
 			// to cache, and for looking for the "no tests to run" message.
 			stdout = io.MultiWriter(stdout, &buf)
@@ -1142,7 +1161,7 @@
 
 	cmd := exec.Command(args[0], args[1:]...)
 	cmd.Dir = a.Package.Dir
-	cmd.Env = base.EnvForDir(cmd.Dir, cfg.OrigEnv[:len(cfg.OrigEnv):len(cfg.OrigEnv)])
+	cmd.Env = base.AppendPWD(cfg.OrigEnv[:len(cfg.OrigEnv):len(cfg.OrigEnv)], cmd.Dir)
 	cmd.Stdout = stdout
 	cmd.Stderr = stdout
 
@@ -1209,7 +1228,7 @@
 
 	if err == nil {
 		norun := ""
-		if !testShowPass && !testJSON {
+		if !testShowPass() && !testJSON {
 			buf.Reset()
 		}
 		if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) {
@@ -1284,16 +1303,13 @@
 			"-test.parallel",
 			"-test.run",
 			"-test.short",
+			"-test.timeout",
 			"-test.v":
 			// These are cacheable.
 			// Note that this list is documented above,
 			// so if you add to this list, update the docs too.
 			cacheArgs = append(cacheArgs, arg)
 
-		case "-test.timeout":
-			// Special case: this is cacheable but ignored during the hash.
-			// Do not add to cacheArgs.
-
 		default:
 			// nothing else is cacheable
 			if cache.DebugTest {
diff --git a/libgo/go/cmd/go/internal/test/testflag.go b/libgo/go/cmd/go/internal/test/testflag.go
index e214b15..1ff34f7 100644
--- a/libgo/go/cmd/go/internal/test/testflag.go
+++ b/libgo/go/cmd/go/internal/test/testflag.go
@@ -5,81 +5,197 @@
 package test
 
 import (
+	"errors"
 	"flag"
+	"fmt"
 	"os"
+	"path/filepath"
 	"strings"
+	"time"
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/cmdflag"
-	"cmd/go/internal/str"
 	"cmd/go/internal/work"
 )
 
-const cmd = "test"
+//go:generate go run ./genflags.go
 
 // The flag handling part of go test is large and distracting.
-// We can't use the flag package because some of the flags from
-// our command line are for us, and some are for 6.out, and
+// We can't use (*flag.FlagSet).Parse because some of the flags from
+// our command line are for us, and some are for the test binary, and
 // some are for both.
 
-// testFlagDefn is the set of flags we process.
-var testFlagDefn = []*cmdflag.Defn{
-	// local.
-	{Name: "c", BoolVar: &testC},
-	{Name: "i", BoolVar: &cfg.BuildI},
-	{Name: "o"},
-	{Name: "cover", BoolVar: &testCover},
-	{Name: "covermode"},
-	{Name: "coverpkg"},
-	{Name: "exec"},
-	{Name: "json", BoolVar: &testJSON},
-	{Name: "vet"},
+func init() {
+	work.AddBuildFlags(CmdTest, work.OmitVFlag)
 
-	// Passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v.
-	{Name: "bench", PassToTest: true},
-	{Name: "benchmem", BoolVar: new(bool), PassToTest: true},
-	{Name: "benchtime", PassToTest: true},
-	{Name: "blockprofile", PassToTest: true},
-	{Name: "blockprofilerate", PassToTest: true},
-	{Name: "count", PassToTest: true},
-	{Name: "coverprofile", PassToTest: true},
-	{Name: "cpu", PassToTest: true},
-	{Name: "cpuprofile", PassToTest: true},
-	{Name: "failfast", BoolVar: new(bool), PassToTest: true},
-	{Name: "list", PassToTest: true},
-	{Name: "memprofile", PassToTest: true},
-	{Name: "memprofilerate", PassToTest: true},
-	{Name: "mutexprofile", PassToTest: true},
-	{Name: "mutexprofilefraction", PassToTest: true},
-	{Name: "outputdir", PassToTest: true},
-	{Name: "parallel", PassToTest: true},
-	{Name: "run", PassToTest: true},
-	{Name: "short", BoolVar: new(bool), PassToTest: true},
-	{Name: "timeout", PassToTest: true},
-	{Name: "trace", PassToTest: true},
-	{Name: "v", BoolVar: &testV, PassToTest: true},
+	cf := CmdTest.Flag
+	cf.BoolVar(&testC, "c", false, "")
+	cf.BoolVar(&cfg.BuildI, "i", false, "")
+	cf.StringVar(&testO, "o", "", "")
+
+	cf.BoolVar(&testCover, "cover", false, "")
+	cf.Var(coverFlag{(*coverModeFlag)(&testCoverMode)}, "covermode", "")
+	cf.Var(coverFlag{commaListFlag{&testCoverPaths}}, "coverpkg", "")
+
+	cf.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "")
+	cf.BoolVar(&testJSON, "json", false, "")
+	cf.Var(&testVet, "vet", "")
+
+	// Register flags to be forwarded to the test binary. We retain variables for
+	// some of them so that cmd/go knows what to do with the test output, or knows
+	// to build the test in a way that supports the use of the flag.
+
+	cf.StringVar(&testBench, "bench", "", "")
+	cf.Bool("benchmem", false, "")
+	cf.String("benchtime", "", "")
+	cf.StringVar(&testBlockProfile, "blockprofile", "", "")
+	cf.String("blockprofilerate", "", "")
+	cf.Int("count", 0, "")
+	cf.Var(coverFlag{stringFlag{&testCoverProfile}}, "coverprofile", "")
+	cf.String("cpu", "", "")
+	cf.StringVar(&testCPUProfile, "cpuprofile", "", "")
+	cf.Bool("failfast", false, "")
+	cf.StringVar(&testList, "list", "", "")
+	cf.StringVar(&testMemProfile, "memprofile", "", "")
+	cf.String("memprofilerate", "", "")
+	cf.StringVar(&testMutexProfile, "mutexprofile", "", "")
+	cf.String("mutexprofilefraction", "", "")
+	cf.Var(outputdirFlag{&testOutputDir}, "outputdir", "")
+	cf.Int("parallel", 0, "")
+	cf.String("run", "", "")
+	cf.Bool("short", false, "")
+	cf.DurationVar(&testTimeout, "timeout", 10*time.Minute, "")
+	cf.StringVar(&testTrace, "trace", "", "")
+	cf.BoolVar(&testV, "v", false, "")
+
+	for name, _ := range passFlagToTest {
+		cf.Var(cf.Lookup(name).Value, "test."+name, "")
+	}
 }
 
-// add build flags to testFlagDefn
-func init() {
-	cmdflag.AddKnownFlags("test", testFlagDefn)
-	var cmd base.Command
-	work.AddBuildFlags(&cmd, work.DefaultBuildFlags)
-	cmd.Flag.VisitAll(func(f *flag.Flag) {
-		if f.Name == "v" {
-			// test overrides the build -v flag
-			return
+// A coverFlag is a flag.Value that also implies -cover.
+type coverFlag struct{ v flag.Value }
+
+func (f coverFlag) String() string { return f.v.String() }
+
+func (f coverFlag) Set(value string) error {
+	if err := f.v.Set(value); err != nil {
+		return err
+	}
+	testCover = true
+	return nil
+}
+
+type coverModeFlag string
+
+func (f *coverModeFlag) String() string { return string(*f) }
+func (f *coverModeFlag) Set(value string) error {
+	switch value {
+	case "", "set", "count", "atomic":
+		*f = coverModeFlag(value)
+		return nil
+	default:
+		return errors.New(`valid modes are "set", "count", or "atomic"`)
+	}
+}
+
+// A commaListFlag is a flag.Value representing a comma-separated list.
+type commaListFlag struct{ vals *[]string }
+
+func (f commaListFlag) String() string { return strings.Join(*f.vals, ",") }
+
+func (f commaListFlag) Set(value string) error {
+	if value == "" {
+		*f.vals = nil
+	} else {
+		*f.vals = strings.Split(value, ",")
+	}
+	return nil
+}
+
+// A stringFlag is a flag.Value representing a single string.
+type stringFlag struct{ val *string }
+
+func (f stringFlag) String() string { return *f.val }
+func (f stringFlag) Set(value string) error {
+	*f.val = value
+	return nil
+}
+
+// outputdirFlag implements the -outputdir flag.
+// It interprets an empty value as the working directory of the 'go' command.
+type outputdirFlag struct {
+	resolved *string
+}
+
+func (f outputdirFlag) String() string { return *f.resolved }
+func (f outputdirFlag) Set(value string) (err error) {
+	if value == "" {
+		// The empty string implies the working directory of the 'go' command.
+		*f.resolved = base.Cwd
+	} else {
+		*f.resolved, err = filepath.Abs(value)
+	}
+	return err
+}
+
+// vetFlag implements the special parsing logic for the -vet flag:
+// a comma-separated list, with a distinguished value "off" and
+// a boolean tracking whether it was set explicitly.
+type vetFlag struct {
+	explicit bool
+	off      bool
+	flags    []string // passed to vet when invoked automatically during 'go test'
+}
+
+func (f *vetFlag) String() string {
+	if f.off {
+		return "off"
+	}
+
+	var buf strings.Builder
+	for i, f := range f.flags {
+		if i > 0 {
+			buf.WriteByte(',')
 		}
-		testFlagDefn = append(testFlagDefn, &cmdflag.Defn{
-			Name:  f.Name,
-			Value: f.Value,
-		})
-	})
+		buf.WriteString(f)
+	}
+	return buf.String()
+}
+
+func (f *vetFlag) Set(value string) error {
+	if value == "" {
+		*f = vetFlag{flags: defaultVetFlags}
+		return nil
+	}
+
+	if value == "off" {
+		*f = vetFlag{
+			explicit: true,
+			off:      true,
+		}
+		return nil
+	}
+
+	if strings.Contains(value, "=") {
+		return fmt.Errorf("-vet argument cannot contain equal signs")
+	}
+	if strings.Contains(value, " ") {
+		return fmt.Errorf("-vet argument is comma-separated list, cannot contain spaces")
+	}
+	*f = vetFlag{explicit: true}
+	for _, arg := range strings.Split(value, ",") {
+		if arg == "" {
+			return fmt.Errorf("-vet argument contains empty list element")
+		}
+		f.flags = append(f.flags, "-"+arg)
+	}
+	return nil
 }
 
 // testFlags processes the command line, grabbing -x and -c, rewriting known flags
-// to have "test" before them, and reading the command line for the 6.out.
+// to have "test" before them, and reading the command line for the test binary.
 // Unfortunately for us, we need to do our own flag processing because go test
 // grabs some flags but otherwise its command line is just a holding place for
 // pkg.test's arguments.
@@ -87,117 +203,154 @@
 // to allow both
 //	go test fmt -custom-flag-for-fmt-test
 //	go test -x math
-func testFlags(usage func(), args []string) (packageNames, passToTest []string) {
-	goflags := cmdflag.FindGOFLAGS(testFlagDefn)
-	args = str.StringList(goflags, args)
-	inPkg := false
-	var explicitArgs []string
-	for i := 0; i < len(args); i++ {
-		if !strings.HasPrefix(args[i], "-") {
-			if !inPkg && packageNames == nil {
-				// First package name we've seen.
-				inPkg = true
-			}
-			if inPkg {
-				packageNames = append(packageNames, args[i])
-				continue
-			}
+func testFlags(args []string) (packageNames, passToTest []string) {
+	base.SetFromGOFLAGS(&CmdTest.Flag)
+	addFromGOFLAGS := map[string]bool{}
+	CmdTest.Flag.Visit(func(f *flag.Flag) {
+		if short := strings.TrimPrefix(f.Name, "test."); passFlagToTest[short] {
+			addFromGOFLAGS[f.Name] = true
+		}
+	})
+
+	explicitArgs := make([]string, 0, len(args))
+	inPkgList := false
+	for len(args) > 0 {
+		f, remainingArgs, err := cmdflag.ParseOne(&CmdTest.Flag, args)
+
+		if errors.Is(err, flag.ErrHelp) {
+			exitWithUsage()
 		}
 
-		if inPkg {
-			// Found an argument beginning with "-"; end of package list.
-			inPkg = false
+		if errors.Is(err, cmdflag.ErrFlagTerminator) {
+			// 'go list' allows package arguments to be named either before or after
+			// the terminator, but 'go test' has historically allowed them only
+			// before. Preserve that behavior and treat all remaining arguments —
+			// including the terminator itself! — as arguments to the test.
+			explicitArgs = append(explicitArgs, args...)
+			break
 		}
 
-		f, value, extraWord := cmdflag.Parse(cmd, usage, testFlagDefn, args, i)
-		if f == nil {
-			// This is a flag we do not know; we must assume
-			// that any args we see after this might be flag
-			// arguments, not package names.
-			inPkg = false
-			if packageNames == nil {
-				// make non-nil: we have seen the empty package list
-				packageNames = []string{}
-			}
-			if args[i] == "-args" || args[i] == "--args" {
-				// -args or --args signals that everything that follows
-				// should be passed to the test.
-				explicitArgs = args[i+1:]
+		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
 			}
-			passToTest = append(passToTest, args[i])
+
+			inPkgList = true
+			packageNames = append(packageNames, nf.RawArg)
+			args = remainingArgs // Consume the package name.
 			continue
 		}
-		if i < len(goflags) {
-			f.Present = false // Not actually present on the command line.
+
+		if inPkgList {
+			// This argument is syntactically a flag, so if we were in the package
+			// list we're not anymore.
+			inPkgList = false
 		}
-		if f.Value != nil {
-			if err := f.Value.Set(value); err != nil {
-				base.Fatalf("invalid flag argument for -%s: %v", f.Name, err)
+
+		if nd := (cmdflag.FlagNotDefinedError{}); errors.As(err, &nd) {
+			// This is a flag we do not know. We must assume that any args we see
+			// after this might be flag arguments, not package names, so make
+			// packageNames non-nil to indicate that the package list is complete.
+			//
+			// (Actually, we only strictly need to assume that if the flag is not of
+			// the form -x=value, but making this more precise would be a breaking
+			// change in the command line API.)
+			if packageNames == nil {
+				packageNames = []string{}
 			}
-		} else {
-			// Test-only flags.
-			// Arguably should be handled by f.Value, but aren't.
-			switch f.Name {
-			// bool flags.
-			case "c", "i", "v", "cover", "json":
-				cmdflag.SetBool(cmd, f.BoolVar, value)
-				if f.Name == "json" && testJSON {
-					passToTest = append(passToTest, "-test.v=true")
-				}
-			case "o":
-				testO = value
-				testNeedBinary = true
-			case "exec":
-				xcmd, err := str.SplitQuotedFields(value)
-				if err != nil {
-					base.Fatalf("invalid flag argument for -%s: %v", f.Name, err)
-				}
-				work.ExecCmd = xcmd
-			case "bench":
-				// record that we saw the flag; don't care about the value
-				testBench = true
-			case "list":
-				testList = true
-			case "timeout":
-				testTimeout = value
-			case "blockprofile", "cpuprofile", "memprofile", "mutexprofile":
-				testProfile = "-" + f.Name
-				testNeedBinary = true
-			case "trace":
-				testProfile = "-trace"
-			case "coverpkg":
-				testCover = true
-				if value == "" {
-					testCoverPaths = nil
-				} else {
-					testCoverPaths = strings.Split(value, ",")
-				}
-			case "coverprofile":
-				testCover = true
-				testCoverProfile = value
-			case "covermode":
-				switch value {
-				case "set", "count", "atomic":
-					testCoverMode = value
-				default:
-					base.Fatalf("invalid flag argument for -covermode: %q", value)
-				}
-				testCover = true
-			case "outputdir":
-				testOutputDir = value
-			case "vet":
-				testVetList = value
+
+			if nd.RawArg == "-args" || nd.RawArg == "--args" {
+				// -args or --args signals that everything that follows
+				// should be passed to the test.
+				explicitArgs = append(explicitArgs, remainingArgs...)
+				break
 			}
+
+			explicitArgs = append(explicitArgs, nd.RawArg)
+			args = remainingArgs
+			continue
 		}
-		if extraWord {
-			i++
+
+		if err != nil {
+			fmt.Fprintln(os.Stderr, err)
+			exitWithUsage()
 		}
-		if f.PassToTest {
-			passToTest = append(passToTest, "-test."+f.Name+"="+value)
+
+		if short := strings.TrimPrefix(f.Name, "test."); passFlagToTest[short] {
+			explicitArgs = append(explicitArgs, fmt.Sprintf("-test.%s=%v", short, f.Value))
+
+			// This flag has been overridden explicitly, so don't forward its implicit
+			// value from GOFLAGS.
+			delete(addFromGOFLAGS, short)
+			delete(addFromGOFLAGS, "test."+short)
+		}
+
+		args = remainingArgs
+	}
+
+	var injectedFlags []string
+	if testJSON {
+		// If converting to JSON, we need the full output in order to pipe it to
+		// test2json.
+		injectedFlags = append(injectedFlags, "-test.v=true")
+		delete(addFromGOFLAGS, "v")
+		delete(addFromGOFLAGS, "test.v")
+	}
+
+	// Inject flags from GOFLAGS before the explicit command-line arguments.
+	// (They must appear before the flag terminator or first non-flag argument.)
+	// Also determine whether flags with awkward defaults have already been set.
+	var timeoutSet, outputDirSet bool
+	CmdTest.Flag.Visit(func(f *flag.Flag) {
+		short := strings.TrimPrefix(f.Name, "test.")
+		if addFromGOFLAGS[f.Name] {
+			injectedFlags = append(injectedFlags, fmt.Sprintf("-test.%s=%v", short, f.Value))
+		}
+		switch short {
+		case "timeout":
+			timeoutSet = true
+		case "outputdir":
+			outputDirSet = true
+		}
+	})
+
+	// 'go test' has a default timeout, but the test binary itself does not.
+	// If the timeout wasn't set (and forwarded) explicitly, add the default
+	// timeout to the command line.
+	if testTimeout > 0 && !timeoutSet {
+		injectedFlags = append(injectedFlags, fmt.Sprintf("-test.timeout=%v", testTimeout))
+	}
+
+	// Similarly, the test binary defaults -test.outputdir to its own working
+	// directory, but 'go test' defaults it to the working directory of the 'go'
+	// command. Set it explicitly if it is needed due to some other flag that
+	// requests output.
+	if testProfile() != "" && !outputDirSet {
+		injectedFlags = append(injectedFlags, "-test.outputdir="+testOutputDir)
+	}
+
+	// If the user is explicitly passing -help or -h, show output
+	// of the test binary so that the help output is displayed
+	// even though the test will exit with success.
+	// This loop is imperfect: it will do the wrong thing for a case
+	// like -args -test.outputdir -help. Such cases are probably rare,
+	// and getting this wrong doesn't do too much harm.
+helpLoop:
+	for _, arg := range explicitArgs {
+		switch arg {
+		case "--":
+			break helpLoop
+		case "-h", "-help", "--help":
+			testHelp = true
+			break helpLoop
 		}
 	}
 
+	// Ensure that -race and -covermode are compatible.
 	if testCoverMode == "" {
 		testCoverMode = "set"
 		if cfg.BuildRace {
@@ -205,35 +358,18 @@
 			testCoverMode = "atomic"
 		}
 	}
-
-	testVetExplicit = testVetList != ""
-	if testVetList != "" && testVetList != "off" {
-		if strings.Contains(testVetList, "=") {
-			base.Fatalf("-vet argument cannot contain equal signs")
-		}
-		if strings.Contains(testVetList, " ") {
-			base.Fatalf("-vet argument is comma-separated list, cannot contain spaces")
-		}
-		list := strings.Split(testVetList, ",")
-		for i, arg := range list {
-			list[i] = "-" + arg
-		}
-		testVetFlags = list
-	}
-
 	if cfg.BuildRace && testCoverMode != "atomic" {
 		base.Fatalf(`-covermode must be "atomic", not %q, when -race is enabled`, testCoverMode)
 	}
 
-	// Tell the test what directory we're running in, so it can write the profiles there.
-	if testProfile != "" && testOutputDir == "" {
-		dir, err := os.Getwd()
-		if err != nil {
-			base.Fatalf("error from os.Getwd: %s", err)
-		}
-		passToTest = append(passToTest, "-test.outputdir", dir)
-	}
+	// Forward any unparsed arguments (following --args) to the test binary.
+	return packageNames, append(injectedFlags, explicitArgs...)
+}
 
-	passToTest = append(passToTest, explicitArgs...)
-	return
+func exitWithUsage() {
+	fmt.Fprintf(os.Stderr, "usage: %s\n", CmdTest.UsageLine)
+	fmt.Fprintf(os.Stderr, "Run 'go help %s' and 'go help %s' for details.\n", CmdTest.LongName(), HelpTestflag.LongName())
+
+	base.SetExitStatus(2)
+	base.Exit()
 }
diff --git a/libgo/go/cmd/go/internal/version/version.go b/libgo/go/cmd/go/internal/version/version.go
index 857548c..ac2ae50 100644
--- a/libgo/go/cmd/go/internal/version/version.go
+++ b/libgo/go/cmd/go/internal/version/version.go
@@ -53,6 +53,11 @@
 
 func runVersion(cmd *base.Command, args []string) {
 	if len(args) == 0 {
+		if *versionM || *versionV {
+			fmt.Fprintf(os.Stderr, "go version: flags can only be used with arguments\n")
+			base.SetExitStatus(2)
+			return
+		}
 		fmt.Printf("go version %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)
 		return
 	}
@@ -61,6 +66,7 @@
 		info, err := os.Stat(arg)
 		if err != nil {
 			fmt.Fprintf(os.Stderr, "%v\n", err)
+			base.SetExitStatus(1)
 			continue
 		}
 		if info.IsDir() {
diff --git a/libgo/go/cmd/go/internal/vet/vet.go b/libgo/go/cmd/go/internal/vet/vet.go
index 4e09c0f..4ec58de 100644
--- a/libgo/go/cmd/go/internal/vet/vet.go
+++ b/libgo/go/cmd/go/internal/vet/vet.go
@@ -13,8 +13,12 @@
 	"path/filepath"
 )
 
+// Break init loop.
+func init() {
+	CmdVet.Run = runVet
+}
+
 var CmdVet = &base.Command{
-	Run:         runVet,
 	CustomFlags: true,
 	UsageLine:   "go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]",
 	Short:       "report likely mistakes in packages",
@@ -47,7 +51,7 @@
 func runVet(cmd *base.Command, args []string) {
 	modload.LoadTests = true
 
-	vetFlags, pkgArgs := vetFlags(vetUsage, args)
+	vetFlags, pkgArgs := vetFlags(args)
 
 	work.BuildInit()
 	work.VetFlags = vetFlags
diff --git a/libgo/go/cmd/go/internal/vet/vetflag.go b/libgo/go/cmd/go/internal/vet/vetflag.go
index e3de48b..ef995ef 100644
--- a/libgo/go/cmd/go/internal/vet/vetflag.go
+++ b/libgo/go/cmd/go/internal/vet/vetflag.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"encoding/json"
+	"errors"
 	"flag"
 	"fmt"
 	"log"
@@ -17,7 +18,6 @@
 
 	"cmd/go/internal/base"
 	"cmd/go/internal/cmdflag"
-	"cmd/go/internal/str"
 	"cmd/go/internal/work"
 )
 
@@ -39,37 +39,44 @@
 var vetTool string // -vettool
 
 func init() {
+	work.AddBuildFlags(CmdVet, work.DefaultBuildFlags)
+	CmdVet.Flag.StringVar(&vetTool, "vettool", "", "")
+}
+
+func parseVettoolFlag(args []string) {
 	// Extract -vettool by ad hoc flag processing:
 	// its value is needed even before we can declare
 	// the flags available during main flag processing.
-	for i, arg := range os.Args {
+	for i, arg := range args {
 		if arg == "-vettool" || arg == "--vettool" {
-			if i+1 >= len(os.Args) {
+			if i+1 >= len(args) {
 				log.Fatalf("%s requires a filename", arg)
 			}
-			vetTool = os.Args[i+1]
-			break
+			vetTool = args[i+1]
+			return
 		} else if strings.HasPrefix(arg, "-vettool=") ||
 			strings.HasPrefix(arg, "--vettool=") {
 			vetTool = arg[strings.IndexByte(arg, '=')+1:]
-			break
+			return
 		}
 	}
 }
 
 // vetFlags processes the command line, splitting it at the first non-flag
 // into the list of flags and list of packages.
-func vetFlags(usage func(), args []string) (passToVet, packageNames []string) {
+func vetFlags(args []string) (passToVet, packageNames []string) {
+	parseVettoolFlag(args)
+
 	// Query the vet command for its flags.
-	tool := vetTool
-	if tool != "" {
+	var tool string
+	if vetTool == "" {
+		tool = base.Tool("vet")
+	} else {
 		var err error
-		tool, err = filepath.Abs(tool)
+		tool, err = filepath.Abs(vetTool)
 		if err != nil {
 			log.Fatal(err)
 		}
-	} else {
-		tool = base.Tool("vet")
 	}
 	out := new(bytes.Buffer)
 	vetcmd := exec.Command(tool, "-flags")
@@ -90,95 +97,85 @@
 		base.Exit()
 	}
 
-	// Add vet's flags to vetflagDefn.
+	// Add vet's flags to CmdVet.Flag.
 	//
 	// Some flags, in particular -tags and -v, are known to vet but
-	// also defined as build flags. This works fine, so we don't
-	// define them here but use AddBuildFlags to init them.
+	// also defined as build flags. This works fine, so we omit duplicates here.
 	// However some, like -x, are known to the build but not to vet.
-	var vetFlagDefn []*cmdflag.Defn
+	isVetFlag := make(map[string]bool, len(analysisFlags))
+	cf := CmdVet.Flag
 	for _, f := range analysisFlags {
-		switch f.Name {
-		case "tags", "v":
-			continue
+		isVetFlag[f.Name] = true
+		if cf.Lookup(f.Name) == nil {
+			if f.Bool {
+				cf.Bool(f.Name, false, "")
+			} else {
+				cf.String(f.Name, "", "")
+			}
 		}
-		defn := &cmdflag.Defn{
-			Name:       f.Name,
-			PassToTest: true,
-		}
-		if f.Bool {
-			defn.BoolVar = new(bool)
-		}
-		vetFlagDefn = append(vetFlagDefn, defn)
 	}
 
-	// Add build flags to vetFlagDefn.
-	var cmd base.Command
-	work.AddBuildFlags(&cmd, work.DefaultBuildFlags)
-	// This flag declaration is a placeholder:
-	// -vettool is actually parsed by the init function above.
-	cmd.Flag.StringVar(new(string), "vettool", "", "path to vet tool binary")
-	cmd.Flag.VisitAll(func(f *flag.Flag) {
-		vetFlagDefn = append(vetFlagDefn, &cmdflag.Defn{
-			Name:  f.Name,
-			Value: f.Value,
-		})
+	// Record the set of vet tool flags set by GOFLAGS. We want to pass them to
+	// the vet tool, but only if they aren't overridden by an explicit argument.
+	base.SetFromGOFLAGS(&CmdVet.Flag)
+	addFromGOFLAGS := map[string]bool{}
+	CmdVet.Flag.Visit(func(f *flag.Flag) {
+		if isVetFlag[f.Name] {
+			addFromGOFLAGS[f.Name] = true
+		}
 	})
 
-	// Process args.
-	goflags := cmdflag.FindGOFLAGS(vetFlagDefn)
-	args = str.StringList(goflags, args)
-	for i := 0; i < len(args); i++ {
-		if !strings.HasPrefix(args[i], "-") {
-			return args[:i], args[i:]
+	explicitFlags := make([]string, 0, len(args))
+	for len(args) > 0 {
+		f, remainingArgs, err := cmdflag.ParseOne(&CmdVet.Flag, args)
+
+		if errors.Is(err, flag.ErrHelp) {
+			exitWithUsage()
 		}
 
-		f, value, extraWord := cmdflag.Parse("vet", usage, vetFlagDefn, args, i)
-		if f == nil {
-			fmt.Fprintf(os.Stderr, "vet: flag %q not defined\n", args[i])
-			fmt.Fprintf(os.Stderr, "Run \"go help vet\" for more information\n")
-			base.SetExitStatus(2)
-			base.Exit()
+		if errors.Is(err, cmdflag.ErrFlagTerminator) {
+			// All remaining args must be package names, but the flag terminator is
+			// not included.
+			packageNames = remainingArgs
+			break
 		}
-		if i < len(goflags) {
-			f.Present = false // Not actually present on the command line.
+
+		if nf := (cmdflag.NonFlagError{}); errors.As(err, &nf) {
+			// Everything from here on out — including the argument we just consumed —
+			// must be a package name.
+			packageNames = args
+			break
 		}
-		if f.Value != nil {
-			if err := f.Value.Set(value); err != nil {
-				base.Fatalf("invalid flag argument for -%s: %v", f.Name, err)
-			}
-			keep := f.PassToTest
-			if !keep {
-				// A build flag, probably one we don't want to pass to vet.
-				// Can whitelist.
-				switch f.Name {
-				case "tags", "v":
-					keep = true
-				}
-			}
-			if !keep {
-				// Flags known to the build but not to vet, so must be dropped.
-				if extraWord {
-					args = append(args[:i], args[i+2:]...)
-					extraWord = false
-				} else {
-					args = append(args[:i], args[i+1:]...)
-				}
-				i--
-			}
+
+		if err != nil {
+			fmt.Fprintln(os.Stderr, err)
+			exitWithUsage()
 		}
-		if extraWord {
-			i++
+
+		if isVetFlag[f.Name] {
+			// Forward the raw arguments rather than cleaned equivalents, just in
+			// case the vet tool parses them idiosyncratically.
+			explicitFlags = append(explicitFlags, args[:len(args)-len(remainingArgs)]...)
+
+			// This flag has been overridden explicitly, so don't forward its implicit
+			// value from GOFLAGS.
+			delete(addFromGOFLAGS, f.Name)
 		}
+
+		args = remainingArgs
 	}
-	return args, nil
+
+	// Prepend arguments from GOFLAGS before other arguments.
+	CmdVet.Flag.Visit(func(f *flag.Flag) {
+		if addFromGOFLAGS[f.Name] {
+			passToVet = append(passToVet, fmt.Sprintf("-%s=%s", f.Name, f.Value))
+		}
+	})
+	passToVet = append(passToVet, explicitFlags...)
+	return passToVet, packageNames
 }
 
-var vetUsage func()
-
-func init() { vetUsage = usage } // break initialization cycle
-
-func usage() {
+func exitWithUsage() {
 	fmt.Fprintf(os.Stderr, "usage: %s\n", CmdVet.UsageLine)
 	fmt.Fprintf(os.Stderr, "Run 'go help %s' for details.\n", CmdVet.LongName())
 
diff --git a/libgo/go/cmd/go/internal/web/api.go b/libgo/go/cmd/go/internal/web/api.go
index 209ed68..5708188 100644
--- a/libgo/go/cmd/go/internal/web/api.go
+++ b/libgo/go/cmd/go/internal/web/api.go
@@ -89,7 +89,7 @@
 	}
 	b, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
-		return nil, fmt.Errorf("reading %s: %v", Redacted(u), err)
+		return nil, fmt.Errorf("reading %s: %v", u.Redacted(), err)
 	}
 	return b, nil
 }
@@ -183,21 +183,6 @@
 	return get(security, u)
 }
 
-// Redacted returns a redacted string form of the URL,
-// suitable for printing in error messages.
-// The string form replaces any non-empty password
-// in the original URL with "[redacted]".
-func Redacted(u *url.URL) string {
-	if u.User != nil {
-		if _, ok := u.User.Password(); ok {
-			redacted := *u
-			redacted.User = url.UserPassword(u.User.Username(), "[redacted]")
-			u = &redacted
-		}
-	}
-	return u.String()
-}
-
 // OpenBrowser attempts to open the requested URL in a web browser.
 func OpenBrowser(url string) (opened bool) {
 	return openBrowser(url)
diff --git a/libgo/go/cmd/go/internal/web/http.go b/libgo/go/cmd/go/internal/web/http.go
index 5e4319b..e050980 100644
--- a/libgo/go/cmd/go/internal/web/http.go
+++ b/libgo/go/cmd/go/internal/web/http.go
@@ -13,6 +13,7 @@
 
 import (
 	"crypto/tls"
+	"errors"
 	"fmt"
 	"mime"
 	"net/http"
@@ -47,6 +48,13 @@
 			lastHop := via[len(via)-1].URL
 			return fmt.Errorf("redirected from secure URL %s to insecure URL %s", lastHop, req.URL)
 		}
+
+		// Go's http.DefaultClient allows 10 redirects before returning an error.
+		// The securityPreservingHTTPClient also uses this default policy to avoid
+		// Go command hangs.
+		if len(via) >= 10 {
+			return errors.New("stopped after 10 redirects")
+		}
 		return nil
 	},
 }
@@ -60,14 +68,14 @@
 
 	if os.Getenv("TESTGOPROXY404") == "1" && url.Host == "proxy.golang.org" {
 		res := &Response{
-			URL:        Redacted(url),
+			URL:        url.Redacted(),
 			Status:     "404 testing",
 			StatusCode: 404,
 			Header:     make(map[string][]string),
 			Body:       http.NoBody,
 		}
 		if cfg.BuildX {
-			fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", Redacted(url), res.Status, time.Since(start).Seconds())
+			fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", url.Redacted(), res.Status, time.Since(start).Seconds())
 		}
 		return res, nil
 	}
@@ -78,7 +86,7 @@
 		// We print extra logging in -x mode instead, which traces what
 		// commands are executed.
 		if cfg.BuildX {
-			fmt.Fprintf(os.Stderr, "# get %s\n", Redacted(url))
+			fmt.Fprintf(os.Stderr, "# get %s\n", url.Redacted())
 		}
 
 		req, err := http.NewRequest("GET", url.String(), nil)
@@ -111,7 +119,7 @@
 		fetched, res, err = fetch(secure)
 		if err != nil {
 			if cfg.BuildX {
-				fmt.Fprintf(os.Stderr, "# get %s: %v\n", Redacted(secure), err)
+				fmt.Fprintf(os.Stderr, "# get %s: %v\n", secure.Redacted(), err)
 			}
 			if security != Insecure || url.Scheme == "https" {
 				// HTTPS failed, and we can't fall back to plain HTTP.
@@ -126,9 +134,9 @@
 		case "http":
 			if security == SecureOnly {
 				if cfg.BuildX {
-					fmt.Fprintf(os.Stderr, "# get %s: insecure\n", Redacted(url))
+					fmt.Fprintf(os.Stderr, "# get %s: insecure\n", url.Redacted())
 				}
-				return nil, fmt.Errorf("insecure URL: %s", Redacted(url))
+				return nil, fmt.Errorf("insecure URL: %s", url.Redacted())
 			}
 		case "":
 			if security != Insecure {
@@ -136,9 +144,9 @@
 			}
 		default:
 			if cfg.BuildX {
-				fmt.Fprintf(os.Stderr, "# get %s: unsupported\n", Redacted(url))
+				fmt.Fprintf(os.Stderr, "# get %s: unsupported\n", url.Redacted())
 			}
-			return nil, fmt.Errorf("unsupported scheme: %s", Redacted(url))
+			return nil, fmt.Errorf("unsupported scheme: %s", url.Redacted())
 		}
 
 		insecure := new(urlpkg.URL)
@@ -146,15 +154,15 @@
 		insecure.Scheme = "http"
 		if insecure.User != nil && security != Insecure {
 			if cfg.BuildX {
-				fmt.Fprintf(os.Stderr, "# get %s: insecure credentials\n", Redacted(insecure))
+				fmt.Fprintf(os.Stderr, "# get %s: insecure credentials\n", insecure.Redacted())
 			}
-			return nil, fmt.Errorf("refusing to pass credentials to insecure URL: %s", Redacted(insecure))
+			return nil, fmt.Errorf("refusing to pass credentials to insecure URL: %s", insecure.Redacted())
 		}
 
 		fetched, res, err = fetch(insecure)
 		if err != nil {
 			if cfg.BuildX {
-				fmt.Fprintf(os.Stderr, "# get %s: %v\n", Redacted(insecure), err)
+				fmt.Fprintf(os.Stderr, "# get %s: %v\n", insecure.Redacted(), err)
 			}
 			// HTTP failed, and we already tried HTTPS if applicable.
 			// Report the error from the HTTP attempt.
@@ -165,11 +173,11 @@
 	// Note: accepting a non-200 OK here, so people can serve a
 	// meta import in their http 404 page.
 	if cfg.BuildX {
-		fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", Redacted(fetched), res.Status, time.Since(start).Seconds())
+		fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", fetched.Redacted(), res.Status, time.Since(start).Seconds())
 	}
 
 	r := &Response{
-		URL:        Redacted(fetched),
+		URL:        fetched.Redacted(),
 		Status:     res.Status,
 		StatusCode: res.StatusCode,
 		Header:     map[string][]string(res.Header),
@@ -201,7 +209,7 @@
 
 	if os.IsNotExist(err) {
 		return &Response{
-			URL:        Redacted(u),
+			URL:        u.Redacted(),
 			Status:     http.StatusText(http.StatusNotFound),
 			StatusCode: http.StatusNotFound,
 			Body:       http.NoBody,
@@ -211,7 +219,7 @@
 
 	if os.IsPermission(err) {
 		return &Response{
-			URL:        Redacted(u),
+			URL:        u.Redacted(),
 			Status:     http.StatusText(http.StatusForbidden),
 			StatusCode: http.StatusForbidden,
 			Body:       http.NoBody,
@@ -224,7 +232,7 @@
 	}
 
 	return &Response{
-		URL:        Redacted(u),
+		URL:        u.Redacted(),
 		Status:     http.StatusText(http.StatusOK),
 		StatusCode: http.StatusOK,
 		Body:       f,
diff --git a/libgo/go/cmd/go/internal/work/action.go b/libgo/go/cmd/go/internal/work/action.go
index db422fd..b872928 100644
--- a/libgo/go/cmd/go/internal/work/action.go
+++ b/libgo/go/cmd/go/internal/work/action.go
@@ -42,7 +42,7 @@
 	IsCmdList           bool // running as part of go list; set p.Stale and additional fields below
 	NeedError           bool // list needs p.Error
 	NeedExport          bool // list needs p.Export
-	NeedCompiledGoFiles bool // list needs p.CompiledGoFIles
+	NeedCompiledGoFiles bool // list needs p.CompiledGoFiles
 
 	objdirSeq int // counter for NewObjdir
 	pkgSeq    int
diff --git a/libgo/go/cmd/go/internal/work/build.go b/libgo/go/cmd/go/internal/work/build.go
index e3b25c9..7146c9c 100644
--- a/libgo/go/cmd/go/internal/work/build.go
+++ b/libgo/go/cmd/go/internal/work/build.go
@@ -232,6 +232,7 @@
 	DefaultBuildFlags BuildFlagMask = 0
 	OmitModFlag       BuildFlagMask = 1 << iota
 	OmitModCommonFlags
+	OmitVFlag
 )
 
 // AddBuildFlags adds the flags common to the build, clean, get,
@@ -240,7 +241,9 @@
 	cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "")
 	cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "")
 	cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "")
-	cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "")
+	if mask&OmitVFlag == 0 {
+		cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "")
+	}
 	cmd.Flag.BoolVar(&cfg.BuildX, "x", false, "")
 
 	cmd.Flag.Var(&load.BuildAsmflags, "asmflags", "")
diff --git a/libgo/go/cmd/go/internal/work/build_test.go b/libgo/go/cmd/go/internal/work/build_test.go
index b60f4e2..c33de26 100644
--- a/libgo/go/cmd/go/internal/work/build_test.go
+++ b/libgo/go/cmd/go/internal/work/build_test.go
@@ -222,7 +222,7 @@
 func TestRespectSetgidDir(t *testing.T) {
 	switch runtime.GOOS {
 	case "darwin":
-		if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
+		if runtime.GOARCH == "arm64" {
 			t.Skip("can't set SetGID bit with chmod on iOS")
 		}
 	case "windows", "plan9":
diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go
index 7558a30..6613b6f 100644
--- a/libgo/go/cmd/go/internal/work/buildid.go
+++ b/libgo/go/cmd/go/internal/work/buildid.go
@@ -185,7 +185,7 @@
 
 	cmdline := str.StringList(cfg.BuildToolexec, path, "-V=full")
 	cmd := exec.Command(cmdline[0], cmdline[1:]...)
-	cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
+	cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir)
 	var stdout, stderr bytes.Buffer
 	cmd.Stdout = &stdout
 	cmd.Stderr = &stderr
@@ -244,7 +244,7 @@
 	// compile an empty file on standard input.
 	cmdline := str.StringList(cfg.BuildToolexec, name, "-###", "-x", language, "-c", "-")
 	cmd := exec.Command(cmdline[0], cmdline[1:]...)
-	cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
+	cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir)
 	// Force untranslated output so that we see the string "version".
 	cmd.Env = append(cmd.Env, "LC_ALL=C")
 	out, err := cmd.CombinedOutput()
diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go
index 764291b..d610410 100644
--- a/libgo/go/cmd/go/internal/work/exec.go
+++ b/libgo/go/cmd/go/internal/work/exec.go
@@ -8,11 +8,6 @@
 
 import (
 	"bytes"
-	"cmd/go/internal/base"
-	"cmd/go/internal/cache"
-	"cmd/go/internal/cfg"
-	"cmd/go/internal/load"
-	"cmd/go/internal/str"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -30,6 +25,12 @@
 	"strings"
 	"sync"
 	"time"
+
+	"cmd/go/internal/base"
+	"cmd/go/internal/cache"
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/load"
+	"cmd/go/internal/str"
 )
 
 // actionList returns the list of actions in the dag rooted at root
@@ -490,6 +491,10 @@
 		return nil
 	}
 
+	if err := allowInstall(a); err != nil {
+		return err
+	}
+
 	// make target directory
 	dir, _ := filepath.Split(a.Target)
 	if dir != "" {
@@ -1194,6 +1199,10 @@
 		return err
 	}
 
+	if err := allowInstall(a); err != nil {
+		return err
+	}
+
 	// make target directory
 	dir, _ := filepath.Split(a.Target)
 	if dir != "" {
@@ -1368,6 +1377,10 @@
 }
 
 func (b *Builder) installShlibname(a *Action) error {
+	if err := allowInstall(a); err != nil {
+		return err
+	}
+
 	// TODO: BuildN
 	a1 := a.Deps[0]
 	err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
@@ -1418,6 +1431,10 @@
 	}
 	defer b.flushOutput(a)
 
+	if err := allowInstall(a); err != nil {
+		return err
+	}
+
 	if err := b.Mkdir(a.Objdir); err != nil {
 		return err
 	}
@@ -1483,8 +1500,12 @@
 		// advertise it by touching the mtimes (usually the libraries are up
 		// to date).
 		if !a.buggyInstall && !b.IsCmdList {
-			now := time.Now()
-			os.Chtimes(a.Target, now, now)
+			if cfg.BuildN {
+				b.Showcmd("", "touch %s", a.Target)
+			} else if err := allowInstall(a); err == nil {
+				now := time.Now()
+				os.Chtimes(a.Target, now, now)
+			}
 		}
 		return nil
 	}
@@ -1495,6 +1516,9 @@
 		a.built = a1.built
 		return nil
 	}
+	if err := allowInstall(a); err != nil {
+		return err
+	}
 
 	if err := b.Mkdir(a.Objdir); err != nil {
 		return err
@@ -1524,6 +1548,13 @@
 	return b.moveOrCopyFile(a.Target, a1.built, perm, false)
 }
 
+// allowInstall returns a non-nil error if this invocation of the go command is
+// allowed to install a.Target.
+//
+// (The build of cmd/go running under its own test is forbidden from installing
+// to its original GOROOT.)
+var allowInstall = func(*Action) error { return nil }
+
 // cleanup removes a's object dir to keep the amount of
 // on-disk garbage down in a large build. On an operating system
 // with aggressive buffering, cleaning incrementally like
@@ -1687,6 +1718,10 @@
 		return nil
 	}
 
+	if err := allowInstall(a); err != nil {
+		return err
+	}
+
 	dir, _ := filepath.Split(a.Target)
 	if dir != "" {
 		if err := b.Mkdir(dir); err != nil {
@@ -1927,7 +1962,7 @@
 	cleanup := passLongArgsInResponseFiles(cmd)
 	defer cleanup()
 	cmd.Dir = dir
-	cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
+	cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir)
 	cmd.Env = append(cmd.Env, env...)
 	start := time.Now()
 	err := cmd.Run()
@@ -2134,9 +2169,41 @@
 func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []string, file string, compiler []string) error {
 	file = mkAbs(p.Dir, file)
 	desc := p.ImportPath
-	if !filepath.IsAbs(outfile) {
-		outfile = filepath.Join(p.Dir, outfile)
+	outfile = mkAbs(p.Dir, outfile)
+
+	// Elide source directory paths if -trimpath or GOROOT_FINAL is set.
+	// This is needed for source files (e.g., a .c file in a package directory).
+	// TODO(golang.org/issue/36072): cgo also generates files with #line
+	// directives pointing to the source directory. It should not generate those
+	// when -trimpath is enabled.
+	if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
+		if cfg.BuildTrimpath {
+			// Keep in sync with Action.trimpath.
+			// The trimmed paths are a little different, but we need to trim in the
+			// same situations.
+			var from, toPath string
+			if m := p.Module; m != nil {
+				from = m.Dir
+				toPath = m.Path + "@" + m.Version
+			} else {
+				from = p.Dir
+				toPath = p.ImportPath
+			}
+			// -fdebug-prefix-map requires an absolute "to" path (or it joins the path
+			// with the working directory). Pick something that makes sense for the
+			// target platform.
+			var to string
+			if cfg.BuildContext.GOOS == "windows" {
+				to = filepath.Join(`\\_\_`, toPath)
+			} else {
+				to = filepath.Join("/_", toPath)
+			}
+			flags = append(flags[:len(flags):len(flags)], "-fdebug-prefix-map="+from+"="+to)
+		} else if p.Goroot && cfg.GOROOT_FINAL != cfg.GOROOT {
+			flags = append(flags[:len(flags):len(flags)], "-fdebug-prefix-map="+cfg.GOROOT+"="+cfg.GOROOT_FINAL)
+		}
 	}
+
 	output, err := b.runOut(a, filepath.Dir(file), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(file))
 	if len(output) > 0 {
 		// On FreeBSD 11, when we pass -g to clang 3.8 it
@@ -2375,13 +2442,25 @@
 	if b.flagCache == nil {
 		b.flagCache = make(map[[2]string]bool)
 	}
+
+	tmp := os.DevNull
+	if runtime.GOOS == "windows" {
+		f, err := ioutil.TempFile(b.WorkDir, "")
+		if err != nil {
+			return false
+		}
+		f.Close()
+		tmp = f.Name()
+		defer os.Remove(tmp)
+	}
+
 	// We used to write an empty C file, but that gets complicated with
 	// go build -n. We tried using a file that does not exist, but that
 	// fails on systems with GCC version 4.2.1; that is the last GPLv2
 	// version of GCC, so some systems have frozen on it.
 	// Now we pass an empty file on stdin, which should work at least for
 	// GCC and clang.
-	cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-", "-o", os.DevNull)
+	cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-", "-o", tmp)
 	if cfg.BuildN || cfg.BuildX {
 		b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs))
 		if cfg.BuildN {
@@ -2390,7 +2469,7 @@
 	}
 	cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
 	cmd.Dir = b.WorkDir
-	cmd.Env = base.EnvForDir(cmd.Dir, os.Environ())
+	cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir)
 	cmd.Env = append(cmd.Env, "LC_ALL=C")
 	out, _ := cmd.CombinedOutput()
 	// GCC says "unrecognized command line option".
@@ -2946,13 +3025,13 @@
 	return abs
 }
 
-// passLongArgsInResponseFiles modifies cmd on Windows such that, for
+// passLongArgsInResponseFiles modifies cmd such that, for
 // certain programs, long arguments are passed in "response files", a
 // file on disk with the arguments, with one arg per line. An actual
 // argument starting with '@' means that the rest of the argument is
 // a filename of arguments to expand.
 //
-// See Issue 18468.
+// See issues 18468 (Windows) and 37768 (Darwin).
 func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) {
 	cleanup = func() {} // no cleanup by default
 
@@ -2990,11 +3069,6 @@
 }
 
 func useResponseFile(path string, argLen int) bool {
-	// Unless we're on Windows, don't use response files.
-	if runtime.GOOS != "windows" {
-		return false
-	}
-
 	// Unless the program uses objabi.Flagparse, which understands
 	// response files, don't use response files.
 	// TODO: do we need more commands? asm? cgo? For now, no.
@@ -3007,6 +3081,8 @@
 
 	// Windows has a limit of 32 KB arguments. To be conservative and not
 	// worry about whether that includes spaces or not, just use 30 KB.
+	// Darwin's limit is less clear. The OS claims 256KB, but we've seen
+	// failures with arglen as small as 50KB.
 	if argLen > (30 << 10) {
 		return true
 	}
diff --git a/libgo/go/cmd/go/internal/work/gc.go b/libgo/go/cmd/go/internal/work/gc.go
index 7d17c0c..f1d08e0 100644
--- a/libgo/go/cmd/go/internal/work/gc.go
+++ b/libgo/go/cmd/go/internal/work/gc.go
@@ -37,6 +37,17 @@
 	return base.Tool("link")
 }
 
+func pkgPath(a *Action) string {
+	p := a.Package
+	ppath := p.ImportPath
+	if cfg.BuildBuildmode == "plugin" {
+		ppath = pluginPath(a)
+	} else if p.Name == "main" && !p.Internal.ForceLibrary {
+		ppath = "main"
+	}
+	return ppath
+}
+
 func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) {
 	p := a.Package
 	objdir := a.Objdir
@@ -47,12 +58,7 @@
 		ofile = objdir + out
 	}
 
-	pkgpath := p.ImportPath
-	if cfg.BuildBuildmode == "plugin" {
-		pkgpath = pluginPath(a)
-	} else if p.Name == "main" && !p.Internal.ForceLibrary {
-		pkgpath = "main"
-	}
+	pkgpath := pkgPath(a)
 	gcargs := []string{"-p", pkgpath}
 	if p.Module != nil && p.Module.GoVersion != "" && allowedVersion(p.Module.GoVersion) {
 		gcargs = append(gcargs, "-lang=go"+p.Module.GoVersion)
@@ -162,7 +168,7 @@
 CheckFlags:
 	for _, flag := range gcflags {
 		// Concurrent compilation is presumed incompatible with any gcflags,
-		// except for a small whitelist of commonly used flags.
+		// except for known commonly used flags.
 		// If the user knows better, they can manually add their own -c to the gcflags.
 		switch flag {
 		case "-N", "-l", "-S", "-B", "-C", "-I":
@@ -217,6 +223,10 @@
 // trimpath returns the -trimpath argument to use
 // when compiling the action.
 func (a *Action) trimpath() string {
+	// Keep in sync with Builder.ccompile
+	// The trimmed paths are a little different, but we need to trim in the
+	// same situations.
+
 	// Strip the object directory entirely.
 	objdir := a.Objdir
 	if len(objdir) > 1 && objdir[len(objdir)-1] == filepath.Separator {
@@ -240,7 +250,8 @@
 func asmArgs(a *Action, p *load.Package) []interface{} {
 	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
 	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
-	args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-trimpath", a.trimpath(), "-I", a.Objdir, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, forcedAsmflags, p.Internal.Asmflags}
+	pkgpath := pkgPath(a)
+	args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-p", pkgpath, "-trimpath", a.trimpath(), "-I", a.Objdir, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, forcedAsmflags, p.Internal.Asmflags}
 	if p.ImportPath == "runtime" && cfg.Goarch == "386" {
 		for _, arg := range forcedAsmflags {
 			if arg == "-dynlink" {
diff --git a/libgo/go/cmd/go/internal/work/init.go b/libgo/go/cmd/go/internal/work/init.go
index 9091f98..dad3b10 100644
--- a/libgo/go/cmd/go/internal/work/init.go
+++ b/libgo/go/cmd/go/internal/work/init.go
@@ -10,11 +10,13 @@
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
+	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"flag"
 	"fmt"
 	"os"
 	"path/filepath"
+	"runtime"
 	"strings"
 )
 
@@ -34,6 +36,20 @@
 		}
 		cfg.BuildPkgdir = p
 	}
+
+	// For each experiment that has been enabled in the toolchain, define a
+	// build tag with the same name but prefixed by "goexperiment." which can be
+	// used for compiling alternative files for the experiment. This allows
+	// changes for the experiment, like extra struct fields in the runtime,
+	// without affecting the base non-experiment code at all. [2:] strips the
+	// leading "X:" from objabi.Expstring().
+	exp := objabi.Expstring()[2:]
+	if exp != "none" {
+		experiments := strings.Split(exp, ",")
+		for _, expt := range experiments {
+			cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "goexperiment."+expt)
+		}
+	}
 }
 
 func instrumentInit() {
@@ -69,7 +85,12 @@
 	modeFlag := "-" + mode
 
 	if !cfg.BuildContext.CgoEnabled {
-		fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag)
+		if runtime.GOOS != cfg.Goos || runtime.GOARCH != cfg.Goarch {
+			fmt.Fprintf(os.Stderr, "go %s: %s requires cgo\n", flag.Args()[0], modeFlag)
+		} else {
+			fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag)
+		}
+
 		base.SetExitStatus(2)
 		base.Exit()
 	}
@@ -102,7 +123,7 @@
 			switch cfg.Goos {
 			case "darwin":
 				switch cfg.Goarch {
-				case "arm", "arm64":
+				case "arm64":
 					codegenArg = "-shared"
 				}
 
@@ -134,9 +155,11 @@
 		case "android":
 			codegenArg = "-shared"
 			ldBuildmode = "pie"
+		case "windows":
+			ldBuildmode = "pie"
 		case "darwin":
 			switch cfg.Goarch {
-			case "arm", "arm64":
+			case "arm64":
 				codegenArg = "-shared"
 			}
 			fallthrough
@@ -161,8 +184,12 @@
 		}
 		if gccgo {
 			codegenArg = "-fPIE"
-		} else if cfg.Goos != "aix" {
-			codegenArg = "-shared"
+		} else {
+			switch cfg.Goos {
+			case "aix", "windows":
+			default:
+				codegenArg = "-shared"
+			}
 		}
 		ldBuildmode = "pie"
 	case "shared":
diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go
index 0ce1664..3ee68ac 100644
--- a/libgo/go/cmd/go/internal/work/security.go
+++ b/libgo/go/cmd/go/internal/work/security.go
@@ -184,7 +184,9 @@
 	re(`-Wl,--enable-new-dtags`),
 	re(`-Wl,--end-group`),
 	re(`-Wl,--(no-)?export-dynamic`),
+	re(`-Wl,-E`),
 	re(`-Wl,-framework,[^,@\-][^,]+`),
+	re(`-Wl,--hash-style=(sysv|gnu|both)`),
 	re(`-Wl,-headerpad_max_install_names`),
 	re(`-Wl,--no-undefined`),
 	re(`-Wl,-R([^@\-][^,@]*$)`),
@@ -200,6 +202,7 @@
 	re(`-Wl,-undefined[=,]([^,@\-][^,]+)`),
 	re(`-Wl,-?-unresolved-symbols=[^,]+`),
 	re(`-Wl,--(no-)?warn-([^,]+)`),
+	re(`-Wl,-?-wrap[=,][^,@\-][^,]*`),
 	re(`-Wl,-z,(no)?execstack`),
 	re(`-Wl,-z,relro`),
 
diff --git a/libgo/go/cmd/go/internal/work/security_test.go b/libgo/go/cmd/go/internal/work/security_test.go
index 6b85c40..11e74f2 100644
--- a/libgo/go/cmd/go/internal/work/security_test.go
+++ b/libgo/go/cmd/go/internal/work/security_test.go
@@ -131,6 +131,7 @@
 	{"-mtune=happybirthday"},
 	{"-pic"},
 	{"-pthread"},
+	{"-Wl,--hash-style=both"},
 	{"-Wl,-rpath,foo"},
 	{"-Wl,-rpath,$ORIGIN/foo"},
 	{"-Wl,-R", "/foo"},
@@ -208,6 +209,7 @@
 	{"-Wl,-framework", "-Wl,@Home"},
 	{"-Wl,-framework", "@Home"},
 	{"-Wl,-framework,Chocolate,@Home"},
+	{"-Wl,--hash-style=foo"},
 	{"-x", "--c"},
 	{"-x", "@obj"},
 	{"-Wl,-rpath,@foo"},
diff --git a/libgo/go/cmd/go/internal/work/testgo.go b/libgo/go/cmd/go/internal/work/testgo.go
index 3e623c6..931f49a 100644
--- a/libgo/go/cmd/go/internal/work/testgo.go
+++ b/libgo/go/cmd/go/internal/work/testgo.go
@@ -8,10 +8,41 @@
 
 package work
 
-import "os"
+import (
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/search"
+	"fmt"
+	"os"
+	"path/filepath"
+	"runtime"
+)
 
 func init() {
 	if v := os.Getenv("TESTGO_VERSION"); v != "" {
 		runtimeVersion = v
 	}
+
+	if testGOROOT := os.Getenv("TESTGO_GOROOT"); testGOROOT != "" {
+		// Disallow installs to the GOROOT from which testgo was built.
+		// Installs to other GOROOTs — such as one set explicitly within a test — are ok.
+		allowInstall = func(a *Action) error {
+			if cfg.BuildN {
+				return nil
+			}
+
+			rel := search.InDir(a.Target, testGOROOT)
+			if rel == "" {
+				return nil
+			}
+
+			callerPos := ""
+			if _, file, line, ok := runtime.Caller(1); ok {
+				if shortFile := search.InDir(file, filepath.Join(testGOROOT, "src")); shortFile != "" {
+					file = shortFile
+				}
+				callerPos = fmt.Sprintf("%s:%d: ", file, line)
+			}
+			return fmt.Errorf("%stestgo must not write to GOROOT (installing to %s)", callerPos, filepath.Join("GOROOT", rel))
+		}
+	}
 }
diff --git a/libgo/go/cmd/go/main.go b/libgo/go/cmd/go/main.go
index bb442b5..11913d6 100644
--- a/libgo/go/cmd/go/main.go
+++ b/libgo/go/cmd/go/main.go
@@ -59,6 +59,7 @@
 		version.CmdVersion,
 		vet.CmdVet,
 
+		help.HelpBuildConstraint,
 		help.HelpBuildmode,
 		help.HelpC,
 		help.HelpCache,
@@ -185,7 +186,7 @@
 			if cmd.CustomFlags {
 				args = args[1:]
 			} else {
-				base.SetFromGOFLAGS(cmd.Flag)
+				base.SetFromGOFLAGS(&cmd.Flag)
 				cmd.Flag.Parse(args[1:])
 				args = cmd.Flag.Args()
 			}
diff --git a/libgo/go/cmd/go/note_test.go b/libgo/go/cmd/go/note_test.go
index e94e82b..b2d3179 100644
--- a/libgo/go/cmd/go/note_test.go
+++ b/libgo/go/cmd/go/note_test.go
@@ -20,6 +20,8 @@
 	// both in internal and external linking mode.
 	tg := testgo(t)
 	defer tg.cleanup()
+	tg.parallel()
+
 	tg.tempFile("hello.go", `package main; func main() { print("hello, world\n") }`)
 	const buildID = "TestNoteReading-Build-ID"
 	tg.run("build", "-ldflags", "-buildid="+buildID, "-o", tg.path("hello.exe"), tg.path("hello.go"))
@@ -53,7 +55,7 @@
 		// we've had trouble reading the notes generated by gold.
 		err := tg.doRun([]string{"build", "-ldflags", "-buildid=" + buildID + " -linkmode=external -extldflags=-fuse-ld=gold", "-o", tg.path("hello3.exe"), tg.path("hello.go")})
 		if err != nil {
-			if tg.grepCountBoth("(invalid linker|gold|cannot find 'ld')") > 0 {
+			if tg.grepCountBoth("(invalid linker|gold|cannot find [‘']ld[’'])") > 0 {
 				// It's not an error if gold isn't there. gcc claims it "cannot find 'ld'" if
 				// ld.gold is missing, see issue #22340.
 				t.Log("skipping gold test")
diff --git a/libgo/go/cmd/go/proxy_test.go b/libgo/go/cmd/go/proxy_test.go
index 8214488..2a4d293 100644
--- a/libgo/go/cmd/go/proxy_test.go
+++ b/libgo/go/cmd/go/proxy_test.go
@@ -174,6 +174,25 @@
 		return
 	}
 
+	// Request for $GOPROXY/redirect/<count>/... goes to redirects.
+	if strings.HasPrefix(path, "redirect/") {
+		path = path[len("redirect/"):]
+		if j := strings.Index(path, "/"); j >= 0 {
+			count, err := strconv.Atoi(path[:j])
+			if err != nil {
+				return
+			}
+
+			// The last redirect.
+			if count <= 1 {
+				http.Redirect(w, r, fmt.Sprintf("/mod/%s", path[j+1:]), 302)
+				return
+			}
+			http.Redirect(w, r, fmt.Sprintf("/mod/redirect/%d/%s", count-1, path[j+1:]), 302)
+			return
+		}
+	}
+
 	// Request for $GOPROXY/sumdb/<name>/supported
 	// is checking whether it's OK to access sumdb via the proxy.
 	if path == "sumdb/"+testSumDBName+"/supported" {
diff --git a/libgo/go/cmd/go/script_test.go b/libgo/go/cmd/go/script_test.go
index ec498bb..2e8f18a 100644
--- a/libgo/go/cmd/go/script_test.go
+++ b/libgo/go/cmd/go/script_test.go
@@ -10,6 +10,7 @@
 import (
 	"bytes"
 	"context"
+	"errors"
 	"fmt"
 	"go/build"
 	"internal/testenv"
@@ -30,6 +31,7 @@
 	"cmd/go/internal/robustio"
 	"cmd/go/internal/txtar"
 	"cmd/go/internal/work"
+	"cmd/internal/objabi"
 	"cmd/internal/sys"
 )
 
@@ -76,15 +78,26 @@
 	stderr     string            // standard error from last 'go' command; for 'stderr' command
 	stopped    bool              // test wants to stop early
 	start      time.Time         // time phase started
-	background []backgroundCmd   // backgrounded 'exec' and 'go' commands
+	background []*backgroundCmd  // backgrounded 'exec' and 'go' commands
 }
 
 type backgroundCmd struct {
-	cmd  *exec.Cmd
-	wait <-chan struct{}
-	neg  bool // if true, cmd should fail
+	want           simpleStatus
+	args           []string
+	cancel         context.CancelFunc
+	done           <-chan struct{}
+	err            error
+	stdout, stderr strings.Builder
 }
 
+type simpleStatus string
+
+const (
+	success          simpleStatus = ""
+	failure          simpleStatus = "!"
+	successOrFailure simpleStatus = "?"
+)
+
 var extraEnvKeys = []string{
 	"SYSTEMROOT",         // must be preserved on Windows to find DLLs; golang.org/issue/25210
 	"WINDIR",             // must be preserved on Windows to be able to run PowerShell command; golang.org/issue/30711
@@ -109,12 +122,16 @@
 		"CCACHE_DISABLE=1", // ccache breaks with non-existent HOME
 		"GOARCH=" + runtime.GOARCH,
 		"GOCACHE=" + testGOCACHE,
+		"GODEBUG=" + os.Getenv("GODEBUG"),
 		"GOEXE=" + cfg.ExeSuffix,
+		"GOEXPSTRING=" + objabi.Expstring()[2:],
 		"GOOS=" + runtime.GOOS,
 		"GOPATH=" + filepath.Join(ts.workdir, "gopath"),
 		"GOPROXY=" + proxyURL,
 		"GOPRIVATE=",
 		"GOROOT=" + testGOROOT,
+		"GOROOT_FINAL=" + os.Getenv("GOROOT_FINAL"), // causes spurious rebuilds and breaks the "stale" built-in if not propagated
+		"TESTGO_GOROOT=" + testGOROOT,
 		"GOSUMDB=" + testSumDBVerifierKey,
 		"GONOPROXY=",
 		"GONOSUMDB=",
@@ -181,10 +198,10 @@
 		// before we print PASS. If we return early (e.g., due to a test failure),
 		// don't print anything about the processes that were still running.
 		for _, bg := range ts.background {
-			interruptProcess(bg.cmd.Process)
+			bg.cancel()
 		}
 		for _, bg := range ts.background {
-			<-bg.wait
+			<-bg.done
 		}
 		ts.background = nil
 
@@ -205,7 +222,7 @@
 	// With -v or -testwork, start log with full environment.
 	if *testWork || testing.Verbose() {
 		// Display environment.
-		ts.cmdEnv(false, nil)
+		ts.cmdEnv(success, nil)
 		fmt.Fprintf(&ts.log, "\n")
 		ts.mark = ts.log.Len()
 	}
@@ -245,7 +262,7 @@
 		// Parse input line. Ignore blanks entirely.
 		parsed := ts.parse(line)
 		if parsed.name == "" {
-			if parsed.neg || len(parsed.conds) > 0 {
+			if parsed.want != "" || len(parsed.conds) > 0 {
 				ts.fatalf("missing command")
 			}
 			continue
@@ -324,7 +341,7 @@
 		if cmd == nil {
 			ts.fatalf("unknown command %q", parsed.name)
 		}
-		cmd(ts, parsed.neg, parsed.args)
+		cmd(ts, parsed.want, parsed.args)
 
 		// Command can ask script to stop early.
 		if ts.stopped {
@@ -335,9 +352,9 @@
 	}
 
 	for _, bg := range ts.background {
-		interruptProcess(bg.cmd.Process)
+		bg.cancel()
 	}
-	ts.cmdWait(false, nil)
+	ts.cmdWait(success, nil)
 
 	// Final phase ended.
 	rewind()
@@ -352,7 +369,7 @@
 //
 // NOTE: If you make changes here, update testdata/script/README too!
 //
-var scriptCmds = map[string]func(*testScript, bool, []string){
+var scriptCmds = map[string]func(*testScript, simpleStatus, []string){
 	"addcrlf": (*testScript).cmdAddcrlf,
 	"cc":      (*testScript).cmdCc,
 	"cd":      (*testScript).cmdCd,
@@ -385,7 +402,7 @@
 }
 
 // addcrlf adds CRLF line endings to the named files.
-func (ts *testScript) cmdAddcrlf(neg bool, args []string) {
+func (ts *testScript) cmdAddcrlf(want simpleStatus, args []string) {
 	if len(args) == 0 {
 		ts.fatalf("usage: addcrlf file...")
 	}
@@ -399,21 +416,21 @@
 }
 
 // cc runs the C compiler along with platform specific options.
-func (ts *testScript) cmdCc(neg bool, args []string) {
+func (ts *testScript) cmdCc(want simpleStatus, args []string) {
 	if len(args) < 1 || (len(args) == 1 && args[0] == "&") {
 		ts.fatalf("usage: cc args... [&]")
 	}
 
 	var b work.Builder
 	b.Init()
-	ts.cmdExec(neg, append(b.GccCmd(".", ""), args...))
+	ts.cmdExec(want, append(b.GccCmd(".", ""), args...))
 	robustio.RemoveAll(b.WorkDir)
 }
 
 // cd changes to a different directory.
-func (ts *testScript) cmdCd(neg bool, args []string) {
-	if neg {
-		ts.fatalf("unsupported: ! cd")
+func (ts *testScript) cmdCd(want simpleStatus, args []string) {
+	if want != success {
+		ts.fatalf("unsupported: %v cd", want)
 	}
 	if len(args) != 1 {
 		ts.fatalf("usage: cd dir")
@@ -437,9 +454,9 @@
 }
 
 // chmod changes permissions for a file or directory.
-func (ts *testScript) cmdChmod(neg bool, args []string) {
-	if neg {
-		ts.fatalf("unsupported: ! chmod")
+func (ts *testScript) cmdChmod(want simpleStatus, args []string) {
+	if want != success {
+		ts.fatalf("unsupported: %v chmod", want)
 	}
 	if len(args) < 2 {
 		ts.fatalf("usage: chmod perm paths...")
@@ -459,10 +476,10 @@
 }
 
 // cmp compares two files.
-func (ts *testScript) cmdCmp(neg bool, args []string) {
-	if neg {
+func (ts *testScript) cmdCmp(want simpleStatus, args []string) {
+	if want != success {
 		// It would be strange to say "this file can have any content except this precise byte sequence".
-		ts.fatalf("unsupported: ! cmp")
+		ts.fatalf("unsupported: %v cmp", want)
 	}
 	quiet := false
 	if len(args) > 0 && args[0] == "-q" {
@@ -476,9 +493,9 @@
 }
 
 // cmpenv compares two files with environment variable substitution.
-func (ts *testScript) cmdCmpenv(neg bool, args []string) {
-	if neg {
-		ts.fatalf("unsupported: ! cmpenv")
+func (ts *testScript) cmdCmpenv(want simpleStatus, args []string) {
+	if want != success {
+		ts.fatalf("unsupported: %v cmpenv", want)
 	}
 	quiet := false
 	if len(args) > 0 && args[0] == "-q" {
@@ -524,7 +541,7 @@
 }
 
 // cp copies files, maybe eventually directories.
-func (ts *testScript) cmdCp(neg bool, args []string) {
+func (ts *testScript) cmdCp(want simpleStatus, args []string) {
 	if len(args) < 2 {
 		ts.fatalf("usage: cp src... dst")
 	}
@@ -564,20 +581,21 @@
 			targ = filepath.Join(dst, filepath.Base(src))
 		}
 		err := ioutil.WriteFile(targ, data, mode)
-		if neg {
+		switch want {
+		case failure:
 			if err == nil {
 				ts.fatalf("unexpected command success")
 			}
-		} else {
+		case success:
 			ts.check(err)
 		}
 	}
 }
 
 // env displays or adds to the environment.
-func (ts *testScript) cmdEnv(neg bool, args []string) {
-	if neg {
-		ts.fatalf("unsupported: ! env")
+func (ts *testScript) cmdEnv(want simpleStatus, args []string) {
+	if want != success {
+		ts.fatalf("unsupported: %v env", want)
 	}
 
 	conv := func(s string) string { return s }
@@ -615,86 +633,96 @@
 }
 
 // exec runs the given command.
-func (ts *testScript) cmdExec(neg bool, args []string) {
+func (ts *testScript) cmdExec(want simpleStatus, args []string) {
 	if len(args) < 1 || (len(args) == 1 && args[0] == "&") {
 		ts.fatalf("usage: exec program [args...] [&]")
 	}
 
-	var err error
+	background := false
 	if len(args) > 0 && args[len(args)-1] == "&" {
-		var cmd *exec.Cmd
-		cmd, err = ts.execBackground(args[0], args[1:len(args)-1]...)
-		if err == nil {
-			wait := make(chan struct{})
-			go func() {
-				ctxWait(testCtx, cmd)
-				close(wait)
-			}()
-			ts.background = append(ts.background, backgroundCmd{cmd, wait, neg})
-		}
-		ts.stdout, ts.stderr = "", ""
-	} else {
-		ts.stdout, ts.stderr, err = ts.exec(args[0], args[1:]...)
-		if ts.stdout != "" {
-			fmt.Fprintf(&ts.log, "[stdout]\n%s", ts.stdout)
-		}
-		if ts.stderr != "" {
-			fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr)
-		}
-		if err == nil && neg {
-			ts.fatalf("unexpected command success")
-		}
+		background = true
+		args = args[:len(args)-1]
 	}
 
+	bg, err := ts.startBackground(want, args[0], args[1:]...)
 	if err != nil {
-		fmt.Fprintf(&ts.log, "[%v]\n", err)
-		if testCtx.Err() != nil {
-			ts.fatalf("test timed out while running command")
-		} else if !neg {
-			ts.fatalf("unexpected command failure")
-		}
+		ts.fatalf("unexpected error starting command: %v", err)
 	}
+	if background {
+		ts.stdout, ts.stderr = "", ""
+		ts.background = append(ts.background, bg)
+		return
+	}
+
+	<-bg.done
+	ts.stdout = bg.stdout.String()
+	ts.stderr = bg.stderr.String()
+	if ts.stdout != "" {
+		fmt.Fprintf(&ts.log, "[stdout]\n%s", ts.stdout)
+	}
+	if ts.stderr != "" {
+		fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr)
+	}
+	if bg.err != nil {
+		fmt.Fprintf(&ts.log, "[%v]\n", bg.err)
+	}
+	ts.checkCmd(bg)
 }
 
 // exists checks that the list of files exists.
-func (ts *testScript) cmdExists(neg bool, args []string) {
-	var readonly bool
-	if len(args) > 0 && args[0] == "-readonly" {
-		readonly = true
-		args = args[1:]
+func (ts *testScript) cmdExists(want simpleStatus, args []string) {
+	if want == successOrFailure {
+		ts.fatalf("unsupported: %v exists", want)
+	}
+	var readonly, exec bool
+loop:
+	for len(args) > 0 {
+		switch args[0] {
+		case "-readonly":
+			readonly = true
+			args = args[1:]
+		case "-exec":
+			exec = true
+			args = args[1:]
+		default:
+			break loop
+		}
 	}
 	if len(args) == 0 {
-		ts.fatalf("usage: exists [-readonly] file...")
+		ts.fatalf("usage: exists [-readonly] [-exec] file...")
 	}
 
 	for _, file := range args {
 		file = ts.mkabs(file)
 		info, err := os.Stat(file)
-		if err == nil && neg {
+		if err == nil && want == failure {
 			what := "file"
 			if info.IsDir() {
 				what = "directory"
 			}
 			ts.fatalf("%s %s unexpectedly exists", what, file)
 		}
-		if err != nil && !neg {
+		if err != nil && want == success {
 			ts.fatalf("%s does not exist", file)
 		}
-		if err == nil && !neg && readonly && info.Mode()&0222 != 0 {
+		if err == nil && want == success && readonly && info.Mode()&0222 != 0 {
 			ts.fatalf("%s exists but is writable", file)
 		}
+		if err == nil && want == success && exec && runtime.GOOS != "windows" && info.Mode()&0111 == 0 {
+			ts.fatalf("%s exists but is not executable", file)
+		}
 	}
 }
 
 // go runs the go command.
-func (ts *testScript) cmdGo(neg bool, args []string) {
-	ts.cmdExec(neg, append([]string{testGo}, args...))
+func (ts *testScript) cmdGo(want simpleStatus, args []string) {
+	ts.cmdExec(want, append([]string{testGo}, args...))
 }
 
 // mkdir creates directories.
-func (ts *testScript) cmdMkdir(neg bool, args []string) {
-	if neg {
-		ts.fatalf("unsupported: ! mkdir")
+func (ts *testScript) cmdMkdir(want simpleStatus, args []string) {
+	if want != success {
+		ts.fatalf("unsupported: %v mkdir", want)
 	}
 	if len(args) < 1 {
 		ts.fatalf("usage: mkdir dir...")
@@ -705,9 +733,9 @@
 }
 
 // rm removes files or directories.
-func (ts *testScript) cmdRm(neg bool, args []string) {
-	if neg {
-		ts.fatalf("unsupported: ! rm")
+func (ts *testScript) cmdRm(want simpleStatus, args []string) {
+	if want != success {
+		ts.fatalf("unsupported: %v rm", want)
 	}
 	if len(args) < 1 {
 		ts.fatalf("usage: rm file...")
@@ -720,20 +748,20 @@
 }
 
 // skip marks the test skipped.
-func (ts *testScript) cmdSkip(neg bool, args []string) {
+func (ts *testScript) cmdSkip(want simpleStatus, args []string) {
 	if len(args) > 1 {
 		ts.fatalf("usage: skip [msg]")
 	}
-	if neg {
-		ts.fatalf("unsupported: ! skip")
+	if want != success {
+		ts.fatalf("unsupported: %v skip", want)
 	}
 
 	// Before we mark the test as skipped, shut down any background processes and
 	// make sure they have returned the correct status.
 	for _, bg := range ts.background {
-		interruptProcess(bg.cmd.Process)
+		bg.cancel()
 	}
-	ts.cmdWait(false, nil)
+	ts.cmdWait(success, nil)
 
 	if len(args) == 1 {
 		ts.t.Skip(args[0])
@@ -742,15 +770,18 @@
 }
 
 // stale checks that the named build targets are stale.
-func (ts *testScript) cmdStale(neg bool, args []string) {
+func (ts *testScript) cmdStale(want simpleStatus, args []string) {
 	if len(args) == 0 {
 		ts.fatalf("usage: stale target...")
 	}
-	tmpl := "{{if .Error}}{{.ImportPath}}: {{.Error.Err}}{else}}"
-	if neg {
+	tmpl := "{{if .Error}}{{.ImportPath}}: {{.Error.Err}}{{else}}"
+	switch want {
+	case failure:
 		tmpl += "{{if .Stale}}{{.ImportPath}} is unexpectedly stale{{end}}"
-	} else {
+	case success:
 		tmpl += "{{if not .Stale}}{{.ImportPath}} is unexpectedly NOT stale{{end}}"
+	default:
+		ts.fatalf("unsupported: %v stale", want)
 	}
 	tmpl += "{{end}}"
 	goArgs := append([]string{"list", "-e", "-f=" + tmpl}, args...)
@@ -764,26 +795,30 @@
 }
 
 // stdout checks that the last go command standard output matches a regexp.
-func (ts *testScript) cmdStdout(neg bool, args []string) {
-	scriptMatch(ts, neg, args, ts.stdout, "stdout")
+func (ts *testScript) cmdStdout(want simpleStatus, args []string) {
+	scriptMatch(ts, want, args, ts.stdout, "stdout")
 }
 
 // stderr checks that the last go command standard output matches a regexp.
-func (ts *testScript) cmdStderr(neg bool, args []string) {
-	scriptMatch(ts, neg, args, ts.stderr, "stderr")
+func (ts *testScript) cmdStderr(want simpleStatus, args []string) {
+	scriptMatch(ts, want, args, ts.stderr, "stderr")
 }
 
 // grep checks that file content matches a regexp.
 // Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax.
-func (ts *testScript) cmdGrep(neg bool, args []string) {
-	scriptMatch(ts, neg, args, "", "grep")
+func (ts *testScript) cmdGrep(want simpleStatus, args []string) {
+	scriptMatch(ts, want, args, "", "grep")
 }
 
 // scriptMatch implements both stdout and stderr.
-func scriptMatch(ts *testScript, neg bool, args []string, text, name string) {
+func scriptMatch(ts *testScript, want simpleStatus, args []string, text, name string) {
+	if want == successOrFailure {
+		ts.fatalf("unsupported: %v %s", want, name)
+	}
+
 	n := 0
 	if len(args) >= 1 && strings.HasPrefix(args[0], "-count=") {
-		if neg {
+		if want == failure {
 			ts.fatalf("cannot use -count= with negated match")
 		}
 		var err error
@@ -803,12 +838,12 @@
 	}
 
 	extraUsage := ""
-	want := 1
+	wantArgs := 1
 	if name == "grep" {
 		extraUsage = " file"
-		want = 2
+		wantArgs = 2
 	}
-	if len(args) != want {
+	if len(args) != wantArgs {
 		ts.fatalf("usage: %s [-count=N] 'pattern'%s", name, extraUsage)
 	}
 
@@ -829,14 +864,16 @@
 	// Matching against workdir would be misleading.
 	text = strings.ReplaceAll(text, ts.workdir, "$WORK")
 
-	if neg {
+	switch want {
+	case failure:
 		if re.MatchString(text) {
 			if isGrep && !quiet {
 				fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
 			}
 			ts.fatalf("unexpected match for %#q found in %s: %s", pattern, name, re.FindString(text))
 		}
-	} else {
+
+	case success:
 		if !re.MatchString(text) {
 			if isGrep && !quiet {
 				fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
@@ -856,9 +893,9 @@
 }
 
 // stop stops execution of the test (marking it passed).
-func (ts *testScript) cmdStop(neg bool, args []string) {
-	if neg {
-		ts.fatalf("unsupported: ! stop")
+func (ts *testScript) cmdStop(want simpleStatus, args []string) {
+	if want != success {
+		ts.fatalf("unsupported: %v stop", want)
 	}
 	if len(args) > 1 {
 		ts.fatalf("usage: stop [msg]")
@@ -872,9 +909,9 @@
 }
 
 // symlink creates a symbolic link.
-func (ts *testScript) cmdSymlink(neg bool, args []string) {
-	if neg {
-		ts.fatalf("unsupported: ! symlink")
+func (ts *testScript) cmdSymlink(want simpleStatus, args []string) {
+	if want != success {
+		ts.fatalf("unsupported: %v symlink", want)
 	}
 	if len(args) != 3 || args[1] != "->" {
 		ts.fatalf("usage: symlink file -> target")
@@ -885,9 +922,9 @@
 }
 
 // wait waits for background commands to exit, setting stderr and stdout to their result.
-func (ts *testScript) cmdWait(neg bool, args []string) {
-	if neg {
-		ts.fatalf("unsupported: ! wait")
+func (ts *testScript) cmdWait(want simpleStatus, args []string) {
+	if want != success {
+		ts.fatalf("unsupported: %v wait", want)
 	}
 	if len(args) > 0 {
 		ts.fatalf("usage: wait")
@@ -895,34 +932,24 @@
 
 	var stdouts, stderrs []string
 	for _, bg := range ts.background {
-		<-bg.wait
+		<-bg.done
 
-		args := append([]string{filepath.Base(bg.cmd.Args[0])}, bg.cmd.Args[1:]...)
-		fmt.Fprintf(&ts.log, "[background] %s: %v\n", strings.Join(args, " "), bg.cmd.ProcessState)
+		args := append([]string{filepath.Base(bg.args[0])}, bg.args[1:]...)
+		fmt.Fprintf(&ts.log, "[background] %s: %v\n", strings.Join(args, " "), bg.err)
 
-		cmdStdout := bg.cmd.Stdout.(*strings.Builder).String()
+		cmdStdout := bg.stdout.String()
 		if cmdStdout != "" {
 			fmt.Fprintf(&ts.log, "[stdout]\n%s", cmdStdout)
 			stdouts = append(stdouts, cmdStdout)
 		}
 
-		cmdStderr := bg.cmd.Stderr.(*strings.Builder).String()
+		cmdStderr := bg.stderr.String()
 		if cmdStderr != "" {
 			fmt.Fprintf(&ts.log, "[stderr]\n%s", cmdStderr)
 			stderrs = append(stderrs, cmdStderr)
 		}
 
-		if bg.cmd.ProcessState.Success() {
-			if bg.neg {
-				ts.fatalf("unexpected command success")
-			}
-		} else {
-			if testCtx.Err() != nil {
-				ts.fatalf("test timed out while running command")
-			} else if !bg.neg {
-				ts.fatalf("unexpected command failure")
-			}
-		}
+		ts.checkCmd(bg)
 	}
 
 	ts.stdout = strings.Join(stdouts, "")
@@ -950,58 +977,176 @@
 	}
 }
 
+func (ts *testScript) checkCmd(bg *backgroundCmd) {
+	select {
+	case <-bg.done:
+	default:
+		panic("checkCmd called when not done")
+	}
+
+	if bg.err == nil {
+		if bg.want == failure {
+			ts.fatalf("unexpected command success")
+		}
+		return
+	}
+
+	if errors.Is(bg.err, context.DeadlineExceeded) {
+		ts.fatalf("test timed out while running command")
+	}
+
+	if errors.Is(bg.err, context.Canceled) {
+		// The process was still running at the end of the test.
+		// The test must not depend on its exit status.
+		if bg.want != successOrFailure {
+			ts.fatalf("unexpected background command remaining at test end")
+		}
+		return
+	}
+
+	if bg.want == success {
+		ts.fatalf("unexpected command failure")
+	}
+}
+
 // exec runs the given command line (an actual subprocess, not simulated)
 // in ts.cd with environment ts.env and then returns collected standard output and standard error.
 func (ts *testScript) exec(command string, args ...string) (stdout, stderr string, err error) {
-	cmd := exec.Command(command, args...)
-	cmd.Dir = ts.cd
-	cmd.Env = append(ts.env, "PWD="+ts.cd)
-	var stdoutBuf, stderrBuf strings.Builder
-	cmd.Stdout = &stdoutBuf
-	cmd.Stderr = &stderrBuf
-	if err = cmd.Start(); err == nil {
-		err = ctxWait(testCtx, cmd)
+	bg, err := ts.startBackground(success, command, args...)
+	if err != nil {
+		return "", "", err
 	}
-	return stdoutBuf.String(), stderrBuf.String(), err
+	<-bg.done
+	return bg.stdout.String(), bg.stderr.String(), bg.err
 }
 
-// execBackground starts the given command line (an actual subprocess, not simulated)
+// startBackground starts the given command line (an actual subprocess, not simulated)
 // in ts.cd with environment ts.env.
-func (ts *testScript) execBackground(command string, args ...string) (*exec.Cmd, error) {
+func (ts *testScript) startBackground(want simpleStatus, command string, args ...string) (*backgroundCmd, error) {
+	done := make(chan struct{})
+	bg := &backgroundCmd{
+		want:   want,
+		args:   append([]string{command}, args...),
+		done:   done,
+		cancel: func() {},
+	}
+
+	ctx := context.Background()
+	gracePeriod := 100 * time.Millisecond
+	if deadline, ok := ts.t.Deadline(); ok {
+		timeout := time.Until(deadline)
+		// If time allows, increase the termination grace period to 5% of the
+		// remaining time.
+		if gp := timeout / 20; gp > gracePeriod {
+			gracePeriod = gp
+		}
+
+		// Send the first termination signal with two grace periods remaining.
+		// If it still hasn't finished after the first period has elapsed,
+		// we'll escalate to os.Kill with a second period remaining until the
+		// test deadline..
+		timeout -= 2 * gracePeriod
+
+		if timeout <= 0 {
+			// The test has less than the grace period remaining. There is no point in
+			// even starting the command, because it will be terminated immediately.
+			// Save the expense of starting it in the first place.
+			bg.err = context.DeadlineExceeded
+			close(done)
+			return bg, nil
+		}
+
+		ctx, bg.cancel = context.WithTimeout(ctx, timeout)
+	}
+
 	cmd := exec.Command(command, args...)
 	cmd.Dir = ts.cd
 	cmd.Env = append(ts.env, "PWD="+ts.cd)
-	var stdoutBuf, stderrBuf strings.Builder
-	cmd.Stdout = &stdoutBuf
-	cmd.Stderr = &stderrBuf
-	return cmd, cmd.Start()
-}
-
-// ctxWait is like cmd.Wait, but terminates cmd with os.Interrupt if ctx becomes done.
-//
-// This differs from exec.CommandContext in that it prefers os.Interrupt over os.Kill.
-// (See https://golang.org/issue/21135.)
-func ctxWait(ctx context.Context, cmd *exec.Cmd) error {
-	errc := make(chan error, 1)
-	go func() { errc <- cmd.Wait() }()
-
-	select {
-	case err := <-errc:
-		return err
-	case <-ctx.Done():
-		interruptProcess(cmd.Process)
-		return <-errc
+	cmd.Stdout = &bg.stdout
+	cmd.Stderr = &bg.stderr
+	if err := cmd.Start(); err != nil {
+		bg.cancel()
+		return nil, err
 	}
+
+	go func() {
+		bg.err = waitOrStop(ctx, cmd, stopSignal(), gracePeriod)
+		close(done)
+	}()
+	return bg, nil
 }
 
-// interruptProcess sends os.Interrupt to p if supported, or os.Kill otherwise.
-func interruptProcess(p *os.Process) {
-	if err := p.Signal(os.Interrupt); err != nil {
+// stopSignal returns the appropriate signal to use to request that a process
+// stop execution.
+func stopSignal() os.Signal {
+	if runtime.GOOS == "windows" {
 		// Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on
 		// Windows; using it with os.Process.Signal will return an error.”
 		// Fall back to Kill instead.
-		p.Kill()
+		return os.Kill
 	}
+	return os.Interrupt
+}
+
+// waitOrStop waits for the already-started command cmd by calling its Wait method.
+//
+// If cmd does not return before ctx is done, waitOrStop sends it the given interrupt signal.
+// If killDelay is positive, waitOrStop waits that additional period for Wait to return before sending os.Kill.
+//
+// This function is copied from the one added to x/playground/internal in
+// http://golang.org/cl/228438.
+func waitOrStop(ctx context.Context, cmd *exec.Cmd, interrupt os.Signal, killDelay time.Duration) error {
+	if cmd.Process == nil {
+		panic("waitOrStop called with a nil cmd.Process — missing Start call?")
+	}
+	if interrupt == nil {
+		panic("waitOrStop requires a non-nil interrupt signal")
+	}
+
+	errc := make(chan error)
+	go func() {
+		select {
+		case errc <- nil:
+			return
+		case <-ctx.Done():
+		}
+
+		err := cmd.Process.Signal(interrupt)
+		if err == nil {
+			err = ctx.Err() // Report ctx.Err() as the reason we interrupted.
+		} else if err.Error() == "os: process already finished" {
+			errc <- nil
+			return
+		}
+
+		if killDelay > 0 {
+			timer := time.NewTimer(killDelay)
+			select {
+			// Report ctx.Err() as the reason we interrupted the process...
+			case errc <- ctx.Err():
+				timer.Stop()
+				return
+			// ...but after killDelay has elapsed, fall back to a stronger signal.
+			case <-timer.C:
+			}
+
+			// Wait still hasn't returned.
+			// Kill the process harder to make sure that it exits.
+			//
+			// Ignore any error: if cmd.Process has already terminated, we still
+			// want to send ctx.Err() (or the error from the Interrupt call)
+			// to properly attribute the signal that may have terminated it.
+			_ = cmd.Process.Kill()
+		}
+
+		errc <- err
+	}()
+
+	waitErr := cmd.Wait()
+	if interruptErr := <-errc; interruptErr != nil {
+		return interruptErr
+	}
+	return waitErr
 }
 
 // expand applies environment variable expansion to the string s.
@@ -1044,7 +1189,7 @@
 
 // A command is a complete command parsed from a script.
 type command struct {
-	neg   bool        // if true, expect the command to fail
+	want  simpleStatus
 	conds []condition // all must be satisfied
 	name  string      // the name of the command; must be non-empty
 	args  []string    // shell-expanded arguments following name
@@ -1079,11 +1224,13 @@
 
 		// Command prefix ! means negate the expectations about this command:
 		// go command should fail, match should not be found, etc.
-		if arg == "!" {
-			if cmd.neg {
-				ts.fatalf("duplicated '!' token")
+		// Prefix ? means allow either success or failure.
+		switch want := simpleStatus(arg); want {
+		case failure, successOrFailure:
+			if cmd.want != "" {
+				ts.fatalf("duplicated '!' or '?' token")
 			}
-			cmd.neg = true
+			cmd.want = want
 			return
 		}
 
@@ -1234,6 +1381,8 @@
 }
 
 func TestDiff(t *testing.T) {
+	t.Parallel()
+
 	for _, tt := range diffTests {
 		// Turn spaces into \n.
 		text1 := strings.ReplaceAll(tt.text1, " ", "\n")
diff --git a/libgo/go/cmd/go/testdata/example1_test.go b/libgo/go/cmd/go/testdata/example1_test.go
deleted file mode 100644
index 87e6c0a..0000000
--- a/libgo/go/cmd/go/testdata/example1_test.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2013 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.
-
-// Make sure that go test runs Example_Z before Example_A, preserving source order.
-
-package p
-
-import "fmt"
-
-var n int
-
-func Example_Z() {
-	n++
-	fmt.Println(n)
-	// Output: 1
-}
-
-func Example_A() {
-	n++
-	fmt.Println(n)
-	// Output: 2
-}
diff --git a/libgo/go/cmd/go/testdata/example2_test.go b/libgo/go/cmd/go/testdata/example2_test.go
deleted file mode 100644
index 5d13426..0000000
--- a/libgo/go/cmd/go/testdata/example2_test.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2013 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.
-
-// Make sure that go test runs Example_Y before Example_B, preserving source order.
-
-package p
-
-import "fmt"
-
-func Example_Y() {
-	n++
-	fmt.Println(n)
-	// Output: 3
-}
-
-func Example_B() {
-	n++
-	fmt.Println(n)
-	// Output: 4
-}
diff --git a/libgo/go/cmd/go/testdata/generate/test1.go b/libgo/go/cmd/go/testdata/generate/test1.go
deleted file mode 100644
index 168cfb7..0000000
--- a/libgo/go/cmd/go/testdata/generate/test1.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 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.
-
-// Simple test for go generate.
-
-// We include a build tag that go generate should ignore.
-
-// +build ignore
-
-//go:generate echo Success
-
-package p
diff --git a/libgo/go/cmd/go/testdata/generate/test2.go b/libgo/go/cmd/go/testdata/generate/test2.go
deleted file mode 100644
index 829244a..0000000
--- a/libgo/go/cmd/go/testdata/generate/test2.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2014 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.
-
-// Test that go generate handles command aliases.
-
-//go:generate -command run echo Now is the time
-//go:generate run for all good men
-
-package p
diff --git a/libgo/go/cmd/go/testdata/generate/test3.go b/libgo/go/cmd/go/testdata/generate/test3.go
deleted file mode 100644
index e950da5..0000000
--- a/libgo/go/cmd/go/testdata/generate/test3.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2014 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.
-
-// Test go generate variable substitution.
-
-//go:generate echo $GOARCH $GOFILE:$GOLINE ${GOPACKAGE}abc xyz$GOPACKAGE/$GOFILE/123
-
-package p
diff --git a/libgo/go/cmd/go/testdata/generate/test4.go b/libgo/go/cmd/go/testdata/generate/test4.go
deleted file mode 100644
index 6dae048..0000000
--- a/libgo/go/cmd/go/testdata/generate/test4.go
+++ /dev/null
@@ -1,10 +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.
-
-// Test -run flag
-
-//go:generate echo oh yes my man
-//go:generate echo no, no, a thousand times no
-
-package p
diff --git a/libgo/go/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt b/libgo/go/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt
index bae8b13..606322a 100644
--- a/libgo/go/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt
+++ b/libgo/go/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt
@@ -21,7 +21,13 @@
 	info, _ := debug.ReadBuildInfo()
 	fmt.Fprintf(os.Stdout, "path is %s\n", info.Path)
 	fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version)
+	if r := info.Main.Replace; r != nil {
+		fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version)
+	}
 	for _, m := range info.Deps {
 		fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version)
+		if r := m.Replace; r != nil {
+			fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version)
+		}
 	}
 }
diff --git a/libgo/go/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt b/libgo/go/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt
index 2467418..b9b71e9 100644
--- a/libgo/go/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt
+++ b/libgo/go/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt
@@ -29,7 +29,13 @@
 	info, _ := debug.ReadBuildInfo()
 	fmt.Fprintf(os.Stdout, "path is %s\n", info.Path)
 	fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version)
+	if r := info.Main.Replace; r != nil {
+		fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version)
+	}
 	for _, m := range info.Deps {
 		fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version)
+		if r := m.Replace; r != nil {
+			fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version)
+		}
 	}
 }
diff --git a/libgo/go/cmd/go/testdata/norunexample/example_test.go b/libgo/go/cmd/go/testdata/norunexample/example_test.go
deleted file mode 100644
index e158305..0000000
--- a/libgo/go/cmd/go/testdata/norunexample/example_test.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package pkg_test
-
-import "os"
-
-func init() {
-	os.Stdout.Write([]byte("File with non-runnable example was built.\n"))
-}
-
-func Example_test() {
-	// This test will not be run, it has no "Output:" comment.
-}
diff --git a/libgo/go/cmd/go/testdata/norunexample/test_test.go b/libgo/go/cmd/go/testdata/norunexample/test_test.go
deleted file mode 100644
index d2e9198..0000000
--- a/libgo/go/cmd/go/testdata/norunexample/test_test.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package pkg
-
-import (
-	"os"
-	"testing"
-)
-
-func TestBuilt(t *testing.T) {
-	os.Stdout.Write([]byte("A normal test was executed.\n"))
-}
diff --git a/libgo/go/cmd/go/testdata/print_goroot.go b/libgo/go/cmd/go/testdata/print_goroot.go
deleted file mode 100644
index 91fbf7d..0000000
--- a/libgo/go/cmd/go/testdata/print_goroot.go
+++ /dev/null
@@ -1,14 +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.
-
-package main
-
-import (
-	"fmt"
-	"runtime"
-)
-
-func main() {
-	fmt.Println(runtime.GOROOT())
-}
diff --git a/libgo/go/cmd/go/testdata/rundir/sub/sub.go b/libgo/go/cmd/go/testdata/rundir/sub/sub.go
deleted file mode 100644
index 06ab7d0..0000000
--- a/libgo/go/cmd/go/testdata/rundir/sub/sub.go
+++ /dev/null
@@ -1 +0,0 @@
-package main
diff --git a/libgo/go/cmd/go/testdata/rundir/x.go b/libgo/go/cmd/go/testdata/rundir/x.go
deleted file mode 100644
index 06ab7d0..0000000
--- a/libgo/go/cmd/go/testdata/rundir/x.go
+++ /dev/null
@@ -1 +0,0 @@
-package main
diff --git a/libgo/go/cmd/go/testdata/script/README b/libgo/go/cmd/go/testdata/script/README
index 7dba6b3..76d6651 100644
--- a/libgo/go/cmd/go/testdata/script/README
+++ b/libgo/go/cmd/go/testdata/script/README
@@ -29,13 +29,17 @@
 	GOARCH=<target GOARCH>
 	GOCACHE=<actual GOCACHE being used outside the test>
 	GOEXE=<executable file suffix: .exe on Windows, empty on other systems>
+	GOEXPSTRING=<value of objabi.Expstring(), from GOEXPERIMENT when toolchain built>
 	GOOS=<target GOOS>
 	GOPATH=$WORK/gopath
 	GOPROXY=<local module proxy serving from cmd/go/testdata/mod>
 	GOROOT=<actual GOROOT>
+	GOROOT_FINAL=<actual GOROOT_FINAL>
+	TESTGO_GOROOT=<GOROOT used to build cmd/go, for use in tests that may change GOROOT>
 	HOME=/no-home
 	PATH=<actual PATH>
 	TMPDIR=$WORK/tmp
+	GODEBUG=<actual GODEBUG>
 	devnull=<value of os.DevNull>
 	goversion=<current Go version; for example, 1.12>
 	:=<OS-specific path list separator>
@@ -65,6 +69,10 @@
 (typically go or a matching predicate) must fail, not succeed. Only certain
 commands support this prefix. They are indicated below by [!] in the synopsis.
 
+The command prefix ? indicates that the command on the rest of the line
+may or may not succeed, but the test should continue regardless.
+Commands that support this prefix are indicated by [?].
+
 The command prefix [cond] indicates that the command on the rest of the line
 should only run when the condition is satisfied. The available conditions are:
 
@@ -88,7 +96,7 @@
 
 The commands are:
 
-- [!] cc args... [&]
+- [! | ?] cc args... [&]
   Run the C compiler, the platform specific flags (i.e. `go env GOGCCFLAGS`) will be
   added automatically before args.
 
@@ -110,7 +118,7 @@
   Like cmp, but environment variables are substituted in the file contents
   before the comparison. For example, $GOOS is replaced by the target GOOS.
 
-- [!] cp src... dst
+- [! | ?] cp src... dst
   Copy the listed files to the target file or existing directory.
   src can include "stdout" or "stderr" to use the standard output or standard error
   from the most recent exec or go command.
@@ -122,7 +130,7 @@
   The -r flag causes the values to be escaped using regexp.QuoteMeta
   before being recorded.
 
-- [!] exec program [args...] [&]
+- [! | ?] exec program [args...] [&]
   Run the given executable program with the arguments.
   It must (or must not) succeed.
   Note that 'exec' does not terminate the script (unlike in Unix shells).
@@ -131,14 +139,16 @@
   output and standard error of the previous command is cleared, but the output
   of the background process is buffered — and checking of its exit status is
   delayed — until the next call to 'wait', 'skip', or 'stop' or the end of the
-  test. At the end of the test, any remaining background processes are
-  terminated using os.Interrupt (if supported) or os.Kill.
+  test. If any background processes remain at the end of the test, they
+  are terminated using os.Interrupt (if supported) or os.Kill and the test
+  must not depend upon their exit status.
 
-- [!] exists [-readonly] file...
+- [!] exists [-readonly] [-exec] file...
   Each of the listed files or directories must (or must not) exist.
   If -readonly is given, the files or directories must be unwritable.
+  If -exec is given, the files or directories must be executable.
 
-- [!] go args... [&]
+- [! | ?] go args... [&]
   Run the (test copy of the) go command with the given arguments.
   It must (or must not) succeed.
 
diff --git a/libgo/go/cmd/go/testdata/script/build_gcflags.txt b/libgo/go/cmd/go/testdata/script/build_gcflags.txt
index e0accb1..b472374 100644
--- a/libgo/go/cmd/go/testdata/script/build_gcflags.txt
+++ b/libgo/go/cmd/go/testdata/script/build_gcflags.txt
@@ -7,7 +7,8 @@
 [!linux] skip  # test only works if c-archive implies -shared
 [short] skip
 
-go build -x -buildmode=c-archive -gcflags=all=-shared=false ./override.go
+env GOCACHE=$WORK/gocache  # Looking for compile commands, so need a clean cache.
+go build -x -n -buildmode=c-archive -gcflags=all=-shared=false ./override.go
 stderr '^.*/compile (.* )?-shared (.* )?-shared=false'
 
 -- override.go --
diff --git a/libgo/go/cmd/go/testdata/script/build_trimpath.txt b/libgo/go/cmd/go/testdata/script/build_trimpath.txt
index cfab807..ad78bcf 100644
--- a/libgo/go/cmd/go/testdata/script/build_trimpath.txt
+++ b/libgo/go/cmd/go/testdata/script/build_trimpath.txt
@@ -1,5 +1,9 @@
 [short] skip
 
+# If GOROOT_FINAL is set, 'go build -trimpath' bakes that into the resulting
+# binary instead of GOROOT. Explicitly unset it here.
+env GOROOT_FINAL=
+
 # Set up two identical directories that can be used as GOPATH.
 env GO111MODULE=on
 mkdir $WORK/a/src/paths $WORK/b/src/paths
diff --git a/libgo/go/cmd/go/testdata/script/cmd_import_error.txt b/libgo/go/cmd/go/testdata/script/cmd_import_error.txt
index 685c606..dea76f4 100644
--- a/libgo/go/cmd/go/testdata/script/cmd_import_error.txt
+++ b/libgo/go/cmd/go/testdata/script/cmd_import_error.txt
@@ -5,7 +5,7 @@
 # a clear error in module mode.
 
 ! go list cmd/unknown
-stderr '^can''t load package: package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$'
+stderr '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$'
 
 go list -f '{{range .DepsErrors}}{{.Err}}{{end}}' x.go
 stdout '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$'
diff --git a/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt b/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt
index dce8e39..5374493 100644
--- a/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt
+++ b/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt
@@ -3,6 +3,8 @@
 [!gc] skip 'using -gcflags and -ldflags'
 [short] skip
 
+env GOCACHE=$WORK/gocache  # Looking for compile commands, so need a clean cache.
+
 # -gcflags=-e applies to named packages, not dependencies
 go build -n -v -gcflags=-e z1 z2
 stderr 'compile.* -e.* -p z1'
diff --git a/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt b/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt
index 14cf722..8d38d7b 100644
--- a/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt
+++ b/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt
@@ -1,5 +1,5 @@
 env GO111MODULE=off
-[!short] skip # rebuilds std for alternate architecture
+[short] skip # rebuilds std for alternate architecture
 [gccgo] skip
 
 cd mycmd
@@ -17,10 +17,9 @@
 ! go install mycmd
 ! exists $GOBIN/linux_$GOARCH
 
-# installing standard command should still work
-# (should also be mtime update only if cmd/pack is up-to-date).
-! stale cmd/pack
-[!short] go install cmd/pack
+# The install directory for a cross-compiled standard command should include GOARCH.
+go list -f '{{.Target}}'  cmd/pack
+stdout ${GOROOT}[/\\]pkg[/\\]tool[/\\]${GOOS}_${GOARCH}[/\\]pack$
 
 -- mycmd/x.go --
 package main
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 03169bf..46b0ef4 100644
--- a/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt
+++ b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt
@@ -12,10 +12,6 @@
 # See: https://github.com/golang/go/issues/36739
 [linux] [riscv64] skip
 
-# External linking is not supported on darwin/386 (10.14+).
-# See: https://github.com/golang/go/issues/31751
-[darwin] [386] skip
-
 cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c
 go build -ldflags='-linkmode=external' ./cmd/main.go
 
diff --git a/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt b/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt
index bdb7ffb..82dde45 100644
--- a/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt
+++ b/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt
@@ -17,10 +17,10 @@
 # A single typo-ed pattern for a Go file. This should
 # treat the wrong pattern as if it were a package.
 ! go list ./foo.go/b.go
-stderr 'package ./foo.go/b.go: cannot find package "."'
+stderr '^stat .*[/\\]foo\.go[/\\]b\.go: directory not found$'
 
 # Multiple patterns for Go files with a typo. This should
-# treat the wrong pattern as if it were a non-existint file.
+# treat the wrong pattern as if it were a nonexistent file.
 ! go list ./foo.go/a.go ./foo.go/b.go
 [plan9] stderr 'stat ./foo.go/b.go: ''./foo.go/b.go'' does not exist'
 [windows] stderr './foo.go/b.go: The system cannot find the file specified'
diff --git a/libgo/go/cmd/go/testdata/script/list_importmap.txt b/libgo/go/cmd/go/testdata/script/list_importmap.txt
index 52ee602..f424b98 100644
--- a/libgo/go/cmd/go/testdata/script/list_importmap.txt
+++ b/libgo/go/cmd/go/testdata/script/list_importmap.txt
@@ -16,7 +16,7 @@
 stdout '^flag \[fmt\.test\] MAP: map\[fmt:fmt \[fmt\.test\]\]'
 stdout '^fmt\.test MAP: map\[(.* )?testing:testing \[fmt\.test\]'
 ! stdout '^fmt\.test MAP: map\[(.* )?os:'
-stdout '^fmt\.test IMPORT: \[fmt \[fmt\.test\] fmt_test \[fmt\.test\] os testing \[fmt\.test\] testing/internal/testdeps \[fmt\.test\]\]'
+stdout '^fmt\.test IMPORT: \[fmt \[fmt\.test\] fmt_test \[fmt\.test\] os reflect testing \[fmt\.test\] testing/internal/testdeps \[fmt\.test\]\]'
 
 
 -- a/b/b.go --
diff --git a/libgo/go/cmd/go/testdata/script/list_parse_err.txt b/libgo/go/cmd/go/testdata/script/list_parse_err.txt
index 5aacaa8..3c53458 100644
--- a/libgo/go/cmd/go/testdata/script/list_parse_err.txt
+++ b/libgo/go/cmd/go/testdata/script/list_parse_err.txt
@@ -1,17 +1,45 @@
-# 'go list' should report imports, even if some files have parse errors
+# 'go list' without -e should fail and print errors on stderr.
+! go list ./p
+stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$'
+! go list -f '{{range .Imports}}{{.}} {{end}}' ./p
+stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$'
+! go list -test ./t
+stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ'
+! go list -test -f '{{range .Imports}}{{.}} {{end}}' ./t
+stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ'
+
+# 'go list -e' should report imports, even if some files have parse errors
 # before the import block.
-go list -e -f '{{range .Imports}}{{.}} {{end}}'
+go list -e -f '{{range .Imports}}{{.}} {{end}}' ./p
 stdout '^fmt '
 
+# 'go list' should report the position of the error if there's only one.
+go list -e -f '{{.Error.Pos}} => {{.Error.Err}}' ./p
+stdout 'b.go:[0-9:]+ => expected ''package'', found ''EOF'''
+
+# 'go test' should report the position of the error if there's only one.
+go list -e -test -f '{{if .Error}}{{.Error.Pos}} => {{.Error.Err}}{{end}}' ./t
+stdout 't_test.go:[0-9:]+ => expected declaration, found ʕ'
+
 -- go.mod --
 module m
 
 go 1.13
 
--- a.go --
+-- p/a.go --
 package a
 
 import "fmt"
 
--- b.go --
+-- p/b.go --
 // no package statement
+
+-- t/t_test.go --
+package t
+
+import "testing"
+
+func Test(t *testing.T) {}
+
+// scan error
+ʕ◔ϖ◔ʔ
diff --git a/libgo/go/cmd/go/testdata/script/list_test_imports.txt b/libgo/go/cmd/go/testdata/script/list_test_imports.txt
index b2a6bc4..0342eba 100644
--- a/libgo/go/cmd/go/testdata/script/list_test_imports.txt
+++ b/libgo/go/cmd/go/testdata/script/list_test_imports.txt
@@ -16,6 +16,6 @@
 -- imports.txt --
 a: b
 b:
-b.test: b [b.test], b_test [b.test], os, testing, testing/internal/testdeps
+b.test: b [b.test], b_test [b.test], os, reflect, testing, testing/internal/testdeps
 b [b.test]:
 b_test [b.test]: a [b.test]
diff --git a/libgo/go/cmd/go/testdata/script/list_test_non_go_files.txt b/libgo/go/cmd/go/testdata/script/list_test_non_go_files.txt
index 16b98f4..6b2b633 100644
--- a/libgo/go/cmd/go/testdata/script/list_test_non_go_files.txt
+++ b/libgo/go/cmd/go/testdata/script/list_test_non_go_files.txt
@@ -5,7 +5,7 @@
 stdout '"Err": "named files must be .go files: c.c"'
 
 ! go list -test -json -- c.c x.go
-stderr 'can''t load package: named files must be .go files: c.c'
+stderr '^named files must be \.go files: c\.c$'
 
 -- x.go --
 package main
diff --git a/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt b/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt
index 61e632a..feaf5d2 100644
--- a/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt
@@ -11,12 +11,11 @@
 
 # An import provided by both the main module and the vendor directory
 # should be flagged as an error only when -mod=vendor is set.
-# TODO: This error message is a bit redundant.
 mkdir vendor/example.com/m/importy
 cp $WORK/importy/importy.go vendor/example.com/m/importy/importy.go
 go build example.com/m/importy
 ! go build -mod=vendor example.com/m/importy
-stderr '^can.t load package: package example.com/m/importy: ambiguous import: found package example.com/m/importy in multiple directories:\n\t'$WORK'[/\\]importy\n\t'$WORK'[/\\]vendor[/\\]example.com[/\\]m[/\\]importy$'
+stderr '^ambiguous import: found package example.com/m/importy in multiple directories:\n\t'$WORK'[/\\]importy\n\t'$WORK'[/\\]vendor[/\\]example.com[/\\]m[/\\]importy$'
 
 -- $WORK/go.mod --
 module example.com/m
diff --git a/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt b/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt
index 267c90e..ad22aca 100644
--- a/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_convert_dep.txt
@@ -20,7 +20,6 @@
 ! go list .
 stderr 'cannot find main module'
 ! stderr 'Gopkg.lock'
-! stderr 'go mod init'
 
 -- $WORK/test/Gopkg.lock --
 -- $WORK/test/x/x.go --
diff --git a/libgo/go/cmd/go/testdata/script/mod_convert_git.txt b/libgo/go/cmd/go/testdata/script/mod_convert_git.txt
index ece505a..6ff1eb5 100644
--- a/libgo/go/cmd/go/testdata/script/mod_convert_git.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_convert_git.txt
@@ -18,6 +18,23 @@
 ! go list .
 ! stderr 'go mod init'
 
+# We should also not suggest creating a go.mod file in $GOROOT if its own
+# .git/config has been stripped away and we find one in a parent directory.
+# (https://golang.org/issue/34191)
+env GOROOT=$WORK/parent/goroot
+cd $GOROOT
+! go list .
+! stderr 'go mod init'
+
+cd $GOROOT/doc
+! go list .
+! stderr 'go mod init'
+
 -- $WORK/test/.git/config --
 -- $WORK/test/x/x.go --
 package x // import "m/x"
+-- $WORK/parent/.git/config --
+-- $WORK/parent/goroot/README --
+This directory isn't really a GOROOT, but let's pretend that it is.
+-- $WORK/parent/goroot/doc/README --
+This is a subdirectory of our fake GOROOT.
diff --git a/libgo/go/cmd/go/testdata/script/mod_dot.txt b/libgo/go/cmd/go/testdata/script/mod_dot.txt
index c90074d..c220e99 100644
--- a/libgo/go/cmd/go/testdata/script/mod_dot.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_dot.txt
@@ -8,12 +8,12 @@
 stderr 'go get \.: path .* is not a package in module rooted at .*[/\\]dir$'
 ! go list
 ! stderr 'cannot find module providing package'
-stderr '^can.t load package: package \.: no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$'
+stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$'
 
 cd subdir
 ! go list
 ! stderr 'cannot find module providing package'
-stderr '^can.t load package: package \.: no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$'
+stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$'
 cd ..
 
 # golang.org/issue/30590: if a package is found in the filesystem
@@ -22,7 +22,74 @@
 # to find a module providing the package.
 ! go list ./othermodule
 ! stderr 'cannot find module providing package'
-stderr 'go: directory othermodule is outside main module'
+stderr '^main module \(example\.com\) does not contain package example.com/othermodule$'
+
+# golang.org/issue/27122: 'go build' of a nonexistent directory should produce
+# a helpful "no Go files" error message, not a generic "unknown import path".
+! go list ./subdir
+stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$'
+
+# golang.org/issue/29280: 'go list -e' for a nonexistent directory should
+# report a nonexistent package with an error.
+go list -e -json ./subdir
+stdout '"Incomplete": true'
+
+# golang.org/issue/28155: 'go list ./testdata' should not synthesize underscores.
+go list ./testdata
+stdout '^example.com/testdata'
+
+# golang.org/issue/32921: vendor directories should only be accepted as directories
+# if the directory would actually be used to load the package.
+! go list ./vendor/nonexist
+stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]nonexist$'
+
+! go list ./vendor/pkg
+stderr '^without -mod=vendor, directory '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]pkg has no package path$'
+
+! go list -mod=vendor ./vendor/nonexist
+stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]nonexist$'
+
+! go list -mod=vendor ./vendor/unlisted
+stderr '^directory '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]unlisted is not a package listed in vendor/modules.txt$'
+
+go list -mod=vendor ./vendor/pkg
+stdout '^pkg$'
+
+# Packages within GOROOT should resolve as in any other module,
+# except that -mod=vendor is implied by default.
+[!gccgo] cd $GOROOT/src
+[!gccgo] ! go list .
+[!gccgo] stderr '^no Go files in '$GOROOT'[/\\]src$'
+
+[!gccgo] ! go list ./builtin
+[!gccgo] stderr '^"builtin" is a pseudo-package, not an importable package$'
+
+[!gccgo] ! go list ./debug
+[!gccgo] ! stderr 'cannot find module providing package'
+[!gccgo] stderr '^no Go files in '$GOROOT'[/\\]src[/\\]debug$'
+
+[!gccgo] ! go list ./golang.org/x/tools/cmd/goimports
+[!gccgo] ! stderr 'cannot find module providing package'
+[!gccgo] stderr '^stat '$GOROOT'[/\\]src[/\\]golang.org[/\\]x[/\\]tools[/\\]cmd[/\\]goimports: directory not found'
+
+[!gccgo] go list ./vendor/golang.org/x/net/http2/hpack
+[!gccgo] stdout '^golang.org/x/net/http2/hpack$'
+
+# golang.org/issue/30756: packages in other GOROOTs should not get the special
+# prefixless treatment of GOROOT itself.
+cd $WORK/othergoroot/src
+! go list .
+stderr '^no Go files in '$WORK'[/\\]othergoroot[/\\]src$'
+
+go list ./builtin
+stdout '^std/builtin$'  # Only the "std" in actual $GOROOT is special, and only its "builtin" is special.
+
+! go list ./bytes
+! stderr 'cannot find module providing package'
+stderr '^no Go files in '$WORK'[/\\]othergoroot[/\\]src[/\\]bytes$'
+
+! go list ./vendor/golang.org/x/net/http2/hpack
+stderr '^without -mod=vendor, directory '$WORK'[/\\]othergoroot[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack has no package path$'
 
 -- dir/go.mod --
 module example.com
@@ -34,3 +101,27 @@
 go 1.13
 -- dir/othermodule/om.go --
 package othermodule
+-- dir/testdata/td.go --
+package testdata
+-- dir/vendor/modules.txt --
+# pkg v0.0.0
+pkg
+-- dir/vendor/nonexist/README --
+There are no Go source files here either.
+-- dir/vendor/pkg/pkg.go --
+package pkg
+-- dir/vendor/unlisted/unlisted.go --
+package unlisted
+-- emptyroot/go.mod --
+module example.com/emptyroot
+-- emptyroot/pkg/pkg.go --
+package pkg
+-- $WORK/othergoroot/src/go.mod --
+module std
+go 1.13
+-- $WORK/othergoroot/src/builtin/builtin.go --
+package builtin
+-- $WORK/othergoroot/src/bytes/README --
+There are no Go source files in this directory.
+-- $WORK/othergoroot/src/vendor/golang.org/x/net/http2/hpack --
+package hpack
diff --git a/libgo/go/cmd/go/testdata/script/mod_empty_err.txt b/libgo/go/cmd/go/testdata/script/mod_empty_err.txt
index 729f848..982e6b2 100644
--- a/libgo/go/cmd/go/testdata/script/mod_empty_err.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_empty_err.txt
@@ -4,16 +4,16 @@
 cd $WORK
 
 go list -e -f {{.Error}} .
-stdout 'package \.: no Go files in \$WORK'
+stdout 'no Go files in \$WORK'
 
 go list -e -f {{.Error}} ./empty
-stdout 'package \./empty: no Go files in \$WORK[/\\]empty'
+stdout 'no Go files in \$WORK[/\\]empty'
 
 go list -e -f {{.Error}} ./exclude
-stdout 'package \./exclude: build constraints exclude all Go files in \$WORK[/\\]exclude'
+stdout 'build constraints exclude all Go files in \$WORK[/\\]exclude'
 
 go list -e -f {{.Error}} ./missing
-stdout 'package \./missing: cannot find package "." in:\s*\$WORK[/\\]missing'
+stdout 'stat '$WORK'[/\\]missing: directory not found'
 
 # use 'go build -n' because 'go list' reports no error.
 ! go build -n ./testonly
diff --git a/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt b/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt
index 4911fbb..a20fefd 100644
--- a/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt
@@ -33,11 +33,11 @@
 
 ! go build -mod=readonly ./nonexist
 ! stderr 'import lookup disabled'
-stderr '^can.t load package: package ./nonexist: cannot find package "." in:\n\t'$WORK'[/\\]gopath[/\\]src[/\\]x[/\\]nonexist$'
+stderr '^stat '$GOPATH'[/\\]src[/\\]x[/\\]nonexist: directory not found'
 
 ! go build -mod=readonly ./go.mod
 ! stderr 'import lookup disabled'
-stderr 'can.t load package: package ./go.mod: cannot find package'
+stderr 'main module \(m\) does not contain package m/go.mod'
 
 
 # File system paths and patterns should allow the '@' character.
diff --git a/libgo/go/cmd/go/testdata/script/mod_get_commit.txt b/libgo/go/cmd/go/testdata/script/mod_get_commit.txt
index a906bab..d108242 100644
--- a/libgo/go/cmd/go/testdata/script/mod_get_commit.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_get_commit.txt
@@ -14,6 +14,9 @@
 
 # dropping -d, we should see a build.
 [short] skip
+
+env GOCACHE=$WORK/gocache  # Looking for compile commands, so need a clean cache.
+
 go get -x golang.org/x/text/language@14c0d48
 stderr 'compile|cp|gccgo .*language\.a$'
 
diff --git a/libgo/go/cmd/go/testdata/script/mod_get_main.txt b/libgo/go/cmd/go/testdata/script/mod_get_main.txt
index 403abcd..408a5b5 100644
--- a/libgo/go/cmd/go/testdata/script/mod_get_main.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_get_main.txt
@@ -1,9 +1,18 @@
 env GO111MODULE=on
-[short] skip
+cp go.mod.orig go.mod
+
+# relative and absolute paths must be within the main module.
+! go get -d ..
+stderr '^go get \.\.: path '$WORK'[/\\]gopath is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src$'
+! go get -d $WORK
+stderr '^go get '$WORK': path '$WORK' is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src$'
+! go get -d ../...
+stderr '^go get: pattern \.\./\.\.\.: directory prefix \.\. outside available modules$'
+! go get -d $WORK/...
+stderr '^go get: pattern '$WORK'[/\\]\.\.\.: directory prefix \.\.[/\\]\.\. outside available modules$'
 
 # @patch and @latest within the main module refer to the current version.
 # The main module won't be upgraded, but missing dependencies will be added.
-cp go.mod.orig go.mod
 go get -d rsc.io/x
 grep 'rsc.io/quote v1.5.2' go.mod
 go get -d rsc.io/x@upgrade
@@ -18,7 +27,7 @@
 stderr '^go get rsc.io/x@latest: can.t request explicit version of path in main module$'
 
 # The main module cannot be updated to a specific version.
-! go get rsc.io/x@v0.1.0
+! go get -d rsc.io/x@v0.1.0
 stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$'
 ! go get -d rsc.io/x@v0.1.0
 stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$'
diff --git a/libgo/go/cmd/go/testdata/script/mod_get_tags.txt b/libgo/go/cmd/go/testdata/script/mod_get_tags.txt
index 603c769..e9869e3 100644
--- a/libgo/go/cmd/go/testdata/script/mod_get_tags.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_get_tags.txt
@@ -14,7 +14,8 @@
 [short] skip
 
 # Packages that are only imported in excluded files should not be built.
-go get -x .
+env GOCACHE=$WORK/gocache  # Looking for compile commands, so need a clean cache.
+go get -n -x .
 stderr 'compile.* -p m '
 ! stderr 'compile.* -p example.com/version '
 ! stderr 'compile.* -p rsc.io/quote '
diff --git a/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt b/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt
index 2bd94cd..a9e0ca4 100644
--- a/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt
@@ -10,7 +10,7 @@
 ! go get rsc.io/quote
 stderr 'SECURITY ERROR'
 
-# but GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text
+# GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text
 env GONOSUMDB='*/quote,*/*mple*,golang.org/x'
 go get rsc.io/quote
 rm go.sum
@@ -18,7 +18,18 @@
 env GONOPROXY=none # that is, proxy all despite GOPRIVATE
 go get rsc.io/quote
 
-# and GONOPROXY bypasses proxy
+# When GOPROXY is not empty but contains no entries, an error should be reported.
+env GOPROXY=','
+! go get golang.org/x/text
+stderr '^go get golang.org/x/text: GOPROXY list is not the empty string, but contains no entries$'
+
+# When GOPROXY=off, fetching modules not matched by GONOPROXY fails.
+env GONOPROXY=*/fortune
+env GOPROXY=off
+! go get golang.org/x/text
+stderr '^go get golang.org/x/text: module lookup disabled by GOPROXY=off$'
+
+# GONOPROXY bypasses proxy
 [!net] skip
 [!exec:git] skip
 env GOPRIVATE=none
diff --git a/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt b/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt
index 2e08ae0..e340f18 100644
--- a/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt
@@ -13,12 +13,12 @@
 ! go build -mod=readonly nonexist
 ! stderr 'import lookup disabled'
 ! stderr 'missing dot'
-stderr '^can''t load package: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$'
+stderr '^package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$'
 
 ! go build nonexist
 ! stderr 'import lookup disabled'
 ! stderr 'missing dot'
-stderr '^can''t load package: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$'
+stderr '^package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$'
 
 # Building a nonexistent std package indirectly should also fail usefully.
 
diff --git a/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt b/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt
index 76e0b43..7e1bc9e 100644
--- a/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt
@@ -76,17 +76,17 @@
 go mod edit -require golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(2017-09-15T03:28:32Z\)'
+stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)'
 cd ..
 ! go list -m golang.org/x/text
-stderr 'golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(2017-09-15T03:28:32Z\)'
+stderr 'golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)'
 
 # A 'replace' directive in the main module can replace an invalid timestamp
 # with a valid one.
 go mod edit -replace golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c=golang.org/x/text@14c0d48ead0c
 cd outside
 ! go list -m golang.org/x/text
-stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(2017-09-15T03:28:32Z\)'
+stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)'
 cd ..
 go list -m golang.org/x/text
 stdout 'golang.org/x/text v0.1.1-0.20190915032832-14c0d48ead0c => golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c'
diff --git a/libgo/go/cmd/go/testdata/script/mod_list_dir.txt b/libgo/go/cmd/go/testdata/script/mod_list_dir.txt
index f6994c1..6653435 100644
--- a/libgo/go/cmd/go/testdata/script/mod_list_dir.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_list_dir.txt
@@ -11,11 +11,7 @@
 stdout ^math$
 go list -f '{{.ImportPath}}' .
 stdout ^x$
-! go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
-stderr '^can.t load package: package '$WORK'[/\\]gopath[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2: can only use path@version syntax with .go get.'
 
-go list -e -f '{{with .Error}}{{.}}{{end}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
-stdout '^package '$WORK'[/\\]gopath[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2: can only use path@version syntax with .go get.'
 go mod download rsc.io/quote@v1.5.2
 go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
 stdout '^rsc.io/quote$'
diff --git a/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt b/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt
index d43bbe7..cad7fe2 100644
--- a/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt
@@ -3,10 +3,10 @@
 # Verifies golang.org/issue/29548
 
 env GO111MODULE=on
-go mod download
+go mod download rsc.io/quote@v1.5.1 rsc.io/quote@v1.5.2
 
 ! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2
-stderr 'can only use path@version syntax with .go get.'
+stderr '^directory ..[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2 outside available modules$'
 
 go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.1
 stdout 'rsc.io/quote'
diff --git a/libgo/go/cmd/go/testdata/script/mod_list_std.txt b/libgo/go/cmd/go/testdata/script/mod_list_std.txt
index 8552aeb..76a3b00 100644
--- a/libgo/go/cmd/go/testdata/script/mod_list_std.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_list_std.txt
@@ -14,6 +14,16 @@
 stdout ^cmd/compile
 ! stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm
 
+# GOROOT/src/... should list the packages in std as if it were a module
+# dependency: omitting vendored dependencies and stopping at the 'cmd' module
+# boundary.
+
+go list $GOROOT/src/...
+stdout ^bytes$
+! stdout ^builtin$
+! stdout ^cmd/
+! stdout ^vendor/
+
 
 # Within the std module, listing ./... should omit the 'std' prefix:
 # the package paths should be the same via ./... or the 'std' meta-pattern.
diff --git a/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt b/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt
index a486228..849cf2c 100644
--- a/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt
@@ -10,17 +10,25 @@
 env GOPROXY=$proxy/404,$proxy/410,$proxy
 go get rsc.io/quote@v1.1.0
 
-# get should not walk past other 4xx errors.
+# get should not walk past other 4xx errors if proxies are separated with ','.
 env GOPROXY=$proxy/403,$proxy
 ! go get rsc.io/quote@v1.2.0
 stderr 'reading.*/403/rsc.io/.*: 403 Forbidden'
 
-# get should not walk past non-4xx errors.
+# get should not walk past non-4xx errors if proxies are separated with ','.
 env GOPROXY=$proxy/500,$proxy
 ! go get rsc.io/quote@v1.3.0
 stderr 'reading.*/500/rsc.io/.*: 500 Internal Server Error'
 
-# get should return the final 404/410 if that's all we have.
+# get should walk past other 4xx errors if proxies are separated with '|'.
+env GOPROXY=$proxy/403|https://0.0.0.0|$proxy
+go get rsc.io/quote@v1.2.0
+
+# get should walk past non-4xx errors if proxies are separated with '|'.
+env GOPROXY=$proxy/500|https://0.0.0.0|$proxy
+go get rsc.io/quote@v1.3.0
+
+# get should return the final error if that's all we have.
 env GOPROXY=$proxy/404,$proxy/410
 ! go get rsc.io/quote@v1.4.0
 stderr 'reading.*/410/rsc.io/.*: 410 Gone'
diff --git a/libgo/go/cmd/go/testdata/script/mod_readonly.txt b/libgo/go/cmd/go/testdata/script/mod_readonly.txt
index 751f6e6..ac58126 100644
--- a/libgo/go/cmd/go/testdata/script/mod_readonly.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_readonly.txt
@@ -6,7 +6,7 @@
 go mod edit -fmt
 cp go.mod go.mod.empty
 ! go list all
-stderr '^can''t load package: x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly'
+stderr '^x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly'
 ! stderr '\(\)' # If we don't have a reason for -mod=readonly, don't log an empty one.
 cmp go.mod go.mod.empty
 
@@ -14,7 +14,7 @@
 chmod 0400 go.mod
 env GOFLAGS=
 ! go list all
-stderr '^can''t load package: x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly\n\t\(go.mod file is read-only\.\)$'
+stderr '^x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly\n\t\(go.mod file is read-only\.\)$'
 
 chmod 0600 go.mod
 env GOFLAGS=-mod=readonly
diff --git a/libgo/go/cmd/go/testdata/script/mod_replace_import.txt b/libgo/go/cmd/go/testdata/script/mod_replace_import.txt
index fd5b04a..54b1a12 100644
--- a/libgo/go/cmd/go/testdata/script/mod_replace_import.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_replace_import.txt
@@ -27,9 +27,8 @@
 # module does not contain a package.
 cd fail
 ! go list all
-stdout 'localhost.fail'
-stderr '^can''t load package: m.go:4:2: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$'
-stderr '^can''t load package: m.go:5:2: nonexist@v0.1.0: replacement directory ../nonexist does not exist$'
+stderr '^m.go:4:2: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$'
+stderr '^m.go:5:2: nonexist@v0.1.0: replacement directory ../nonexist does not exist$'
 
 -- go.mod --
 module example.com/m
diff --git a/libgo/go/cmd/go/testdata/script/mod_retention.txt b/libgo/go/cmd/go/testdata/script/mod_retention.txt
index bff4142..1d83e6c 100644
--- a/libgo/go/cmd/go/testdata/script/mod_retention.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_retention.txt
@@ -64,7 +64,7 @@
 # However, that should not remove other redundant requirements.
 cp go.mod.nogo go.mod
 go list all
-cmp go.mod go.mod.redundant
+cmpenv go.mod go.mod.currentgo
 
 
 -- go.mod.tidy --
@@ -133,3 +133,13 @@
 	rsc.io/sampler v1.3.0 // indirect
 	rsc.io/testonly v1.0.0 // indirect
 )
+-- go.mod.currentgo --
+module m
+
+go $goversion
+
+require (
+	rsc.io/quote v1.5.2
+	rsc.io/sampler v1.3.0 // indirect
+	rsc.io/testonly v1.0.0 // indirect
+)
diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt
index 2816691..7bbc3f9 100644
--- a/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt
+++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt
@@ -46,5 +46,22 @@
 rm $GOPATH/pkg/mod/cache/download/sumdb
 rm go.sum
 
+# the error from the last attempted proxy should be returned.
+cp go.mod.orig go.mod
+env GOSUMDB=$sumdb
+env GOPROXY=$proxy/sumdb-404,$proxy/sumdb-503
+! go get -d rsc.io/fortune@v1.0.0
+stderr '503 Service Unavailable'
+rm $GOPATH/pkg/mod/cache/download/sumdb
+rm go.sum
+
+# if proxies are separated with '|', fallback is allowed on any error.
+cp go.mod.orig go.mod
+env GOSUMDB=$sumdb
+env GOPROXY=$proxy/sumdb-503|https://0.0.0.0|$proxy
+go get -d rsc.io/fortune@v1.0.0
+rm $GOPATH/pkg/mod/cache/download/sumdb
+rm go.sum
+
 -- go.mod.orig --
 module m
diff --git a/libgo/go/cmd/go/testdata/script/noncanonical_import.txt b/libgo/go/cmd/go/testdata/script/noncanonical_import.txt
index 7fdc071..018cb01 100644
--- a/libgo/go/cmd/go/testdata/script/noncanonical_import.txt
+++ b/libgo/go/cmd/go/testdata/script/noncanonical_import.txt
@@ -1,9 +1,7 @@
 env GO111MODULE=off
 
 ! go build canonical/d
-stderr 'package canonical/d'
-stderr 'imports canonical/b'
-stderr 'imports canonical/a/: non-canonical'
+stderr '^canonical[/\\]b[/\\]b.go:3:8: non-canonical import path "canonical/a/": should be "canonical/a"$'
 
 -- canonical/a/a.go --
 package a
diff --git a/libgo/go/cmd/go/testdata/script/script_wait.txt b/libgo/go/cmd/go/testdata/script/script_wait.txt
index 3cd4ded..acaccfe 100644
--- a/libgo/go/cmd/go/testdata/script/script_wait.txt
+++ b/libgo/go/cmd/go/testdata/script/script_wait.txt
@@ -19,6 +19,7 @@
 stdout 'foo\nbar'
 
 # The end of the test should interrupt or kill any remaining background
-# programs.
-[!exec:sleep] skip
-! exec sleep 86400 &
+# programs, but that should not cause the test to fail if it does not
+# care about the exit status of those programs.
+[!exec:sleep] stop
+? exec sleep 86400 &
diff --git a/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt b/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt
index 46faca0..57602e9 100644
--- a/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt
+++ b/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt
@@ -29,6 +29,23 @@
 go test testcache -run=TestLookupEnv
 stdout '\(cached\)'
 
+# Changes in arguments forwarded to the test should invalidate cached test
+# results.
+go test testcache -run=TestOSArgs -v hello
+! stdout '\(cached\)'
+stdout 'hello'
+go test testcache -run=TestOSArgs -v goodbye
+! stdout '\(cached\)'
+stdout 'goodbye'
+
+# golang.org/issue/36134: that includes the `-timeout` argument.
+go test testcache -run=TestOSArgs -timeout=20m -v
+! stdout '\(cached\)'
+stdout '-test\.timeout[= ]20m'
+go test testcache -run=TestOSArgs -timeout=5s -v
+! stdout '\(cached\)'
+stdout '-test\.timeout[= ]5s'
+
 # If the test stats a file, changes to the file should invalidate the cache.
 go test testcache -run=FileSize
 go test testcache -run=FileSize
@@ -207,6 +224,10 @@
 		t.Fatal(err)
 	}
 }
+
+func TestOSArgs(t *testing.T) {
+	t.Log(os.Args)
+}
 -- mkold.go --
 package main
 
diff --git a/libgo/go/cmd/go/testdata/script/version.txt b/libgo/go/cmd/go/testdata/script/version.txt
index 4252624..0123ac6 100644
--- a/libgo/go/cmd/go/testdata/script/version.txt
+++ b/libgo/go/cmd/go/testdata/script/version.txt
@@ -1,4 +1,16 @@
+# Without arguments, we just print Go's own version.
+go version
+stdout '^go version'
+
+# Flags without files, or paths to misisng files, should error.
+! go version missing.exe
+! go version -m
+stderr 'with arguments'
+! go version -v
+stderr 'with arguments'
+
 env GO111MODULE=on
+# Skip the builds below if we are running in short mode.
 [short] skip
 
 # Check that 'go version' and 'go version -m' work on a binary built in module mode.
@@ -10,9 +22,7 @@
 stdout '^\tmod\trsc.io/fortune\tv1.0.0'
 
 # Repeat the test with -buildmode=pie.
-# TODO(golang.org/issue/27144): don't skip after -buildmode=pie is implemented
-# on Windows.
-[windows] skip # -buildmode=pie not supported
+[!buildmode:pie] stop
 go build -buildmode=pie -o external.exe rsc.io/fortune
 go version external.exe
 stdout '^external.exe: .+'
@@ -20,5 +30,16 @@
 stdout '^\tpath\trsc.io/fortune'
 stdout '^\tmod\trsc.io/fortune\tv1.0.0'
 
+# Also test PIE with internal linking.
+# currently only supported on linux/amd64, linux/arm64 and windows/amd64.
+[!linux] [!windows] stop
+[!amd64] [!arm64] stop
+go build -buildmode=pie -ldflags=-linkmode=internal -o internal.exe rsc.io/fortune
+go version internal.exe
+stdout '^internal.exe: .+'
+go version -m internal.exe
+stdout '^\tpath\trsc.io/fortune'
+stdout '^\tmod\trsc.io/fortune\tv1.0.0'
+
 -- go.mod --
 module m
diff --git a/libgo/go/cmd/go/testdata/script/vet_flags.txt b/libgo/go/cmd/go/testdata/script/vet_flags.txt
index 2d790c1..b55dada 100644
--- a/libgo/go/cmd/go/testdata/script/vet_flags.txt
+++ b/libgo/go/cmd/go/testdata/script/vet_flags.txt
@@ -3,8 +3,8 @@
 # gccgo doesn't support vet on the standard library
 [gccgo] skip
 
-# Regression test for issue 35837: "go vet -<analyzer> <std package>"
-# did not apply the requested analyzer.
+# Issue 35837: "go vet -<analyzer> <std package>" should use the requested
+# analyzers, not the default analyzers for 'go test'.
 go vet -n -unreachable=false encoding/binary
 stderr '-unreachable=false'
 ! stderr '-unsafeptr=false'
@@ -20,20 +20,54 @@
 stderr '-unsafeptr'
 ! stderr '-unsafeptr=false'
 
-[short] stop
-env GOCACHE=$WORK/gocache
-env GOTMPDIR=$WORK/tmp
-go env GOTMPDIR
-stdout '/tmp'
+# A flag terminator should be allowed before the package list.
+go vet -n -- .
 
-# "go test" on a user package should by default enable an explicit whitelist of analyzers.
+[short] stop
+
+# Analyzer flags should be included from GOFLAGS, and should override
+# the defaults.
+go vet .
+env GOFLAGS='-tags=buggy'
+! go vet .
+stderr 'possible formatting directive'
+
+# Enabling one analyzer in GOFLAGS should disable the rest implicitly...
+env GOFLAGS='-tags=buggy -unsafeptr'
+go vet .
+
+# ...but enabling one on the command line should not disable the analyzers
+# enabled via GOFLAGS.
+env GOFLAGS='-tags=buggy -printf'
+! go vet -unsafeptr
+stderr 'possible formatting directive'
+
+# Analyzer flags don't exist unless we're running 'go vet',
+# and we shouldn't run the vet tool to discover them otherwise.
+# (Maybe someday we'll hard-code the analyzer flags for the default vet
+# tool to make this work, but not right now.)
+env GOFLAGS='-unsafeptr'
+! go list .
+stderr 'go: parsing \$GOFLAGS: unknown flag -unsafeptr'
+env GOFLAGS=
+
+env GOCACHE=$WORK/gocache
+
+# "go test" on a user package should by default enable an explicit list of analyzers.
 go test -x -run=none .
 stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
 
-# "go test" on a standard package should by default disable an explicit blacklist.
+# An explicitly-empty -vet argument should imply the default analyzers.
+go test -x -vet= -run=none .
+stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
+
+# "go test" on a standard package should by default disable an explicit list.
 go test -x -run=none encoding/binary
 stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
 
+go test -x -vet= -run=none encoding/binary
+stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
+
 # Both should allow users to override via the -vet flag.
 go test -x -vet=unreachable -run=none .
 stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg'
@@ -46,3 +80,13 @@
 package x
 -- x_test.go --
 package x
+-- x_tagged.go --
+// +build buggy
+
+package x
+
+import "fmt"
+
+func init() {
+	fmt.Sprint("%s") // oops!
+}
diff --git a/libgo/go/cmd/go/testdata/shadow/root1/src/foo/foo.go b/libgo/go/cmd/go/testdata/shadow/root1/src/foo/foo.go
deleted file mode 100644
index f52652b..0000000
--- a/libgo/go/cmd/go/testdata/shadow/root1/src/foo/foo.go
+++ /dev/null
@@ -1 +0,0 @@
-package foo
diff --git a/libgo/go/cmd/go/testdata/shadow/root1/src/math/math.go b/libgo/go/cmd/go/testdata/shadow/root1/src/math/math.go
deleted file mode 100644
index c91c24e..0000000
--- a/libgo/go/cmd/go/testdata/shadow/root1/src/math/math.go
+++ /dev/null
@@ -1 +0,0 @@
-package math
diff --git a/libgo/go/cmd/go/testdata/shadow/root2/src/foo/foo.go b/libgo/go/cmd/go/testdata/shadow/root2/src/foo/foo.go
deleted file mode 100644
index f52652b..0000000
--- a/libgo/go/cmd/go/testdata/shadow/root2/src/foo/foo.go
+++ /dev/null
@@ -1 +0,0 @@
-package foo
diff --git a/libgo/go/cmd/go/testdata/src/cgotest/m.go b/libgo/go/cmd/go/testdata/src/cgotest/m.go
deleted file mode 100644
index 4d68307..0000000
--- a/libgo/go/cmd/go/testdata/src/cgotest/m.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package cgotest
-
-import "C"
-
-var _ C.int
diff --git a/libgo/go/cmd/go/testdata/src/coverasm/p.go b/libgo/go/cmd/go/testdata/src/coverasm/p.go
deleted file mode 100644
index ab0c300..0000000
--- a/libgo/go/cmd/go/testdata/src/coverasm/p.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package p
-
-func f()
-
-func g() {
-	println("g")
-}
diff --git a/libgo/go/cmd/go/testdata/src/coverasm/p.s b/libgo/go/cmd/go/testdata/src/coverasm/p.s
deleted file mode 100644
index 5e728f9..0000000
--- a/libgo/go/cmd/go/testdata/src/coverasm/p.s
+++ /dev/null
@@ -1,2 +0,0 @@
-// empty asm file,
-// so go test doesn't complain about declaration of f in p.go.
diff --git a/libgo/go/cmd/go/testdata/src/coverasm/p_test.go b/libgo/go/cmd/go/testdata/src/coverasm/p_test.go
deleted file mode 100644
index 3cb3bd5..0000000
--- a/libgo/go/cmd/go/testdata/src/coverasm/p_test.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package p
-
-import "testing"
-
-func Test(t *testing.T) {
-	g()
-}
diff --git a/libgo/go/cmd/go/testdata/src/coverbad/p.go b/libgo/go/cmd/go/testdata/src/coverbad/p.go
deleted file mode 100644
index 16504a4..0000000
--- a/libgo/go/cmd/go/testdata/src/coverbad/p.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package p
-
-func f() {
-	g()
-}
diff --git a/libgo/go/cmd/go/testdata/src/coverbad/p1.go b/libgo/go/cmd/go/testdata/src/coverbad/p1.go
deleted file mode 100644
index 2d25c8e..0000000
--- a/libgo/go/cmd/go/testdata/src/coverbad/p1.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package p
-
-import "C"
-
-func h() {
-	j()
-}
diff --git a/libgo/go/cmd/go/testdata/src/coverbad/p_test.go b/libgo/go/cmd/go/testdata/src/coverbad/p_test.go
deleted file mode 100644
index 3a876d6..0000000
--- a/libgo/go/cmd/go/testdata/src/coverbad/p_test.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package p
-
-import "testing"
-
-func Test(t *testing.T) {}
diff --git a/libgo/go/cmd/go/testdata/src/coverdep/p.go b/libgo/go/cmd/go/testdata/src/coverdep/p.go
deleted file mode 100644
index 6baf6d5..0000000
--- a/libgo/go/cmd/go/testdata/src/coverdep/p.go
+++ /dev/null
@@ -1,6 +0,0 @@
-package p
-
-import _ "coverdep/p1"
-
-func F() {
-}
diff --git a/libgo/go/cmd/go/testdata/src/coverdep/p1/p1.go b/libgo/go/cmd/go/testdata/src/coverdep/p1/p1.go
deleted file mode 100644
index 8ae793d..0000000
--- a/libgo/go/cmd/go/testdata/src/coverdep/p1/p1.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package p1
-
-import _ "errors"
diff --git a/libgo/go/cmd/go/testdata/src/coverdep/p_test.go b/libgo/go/cmd/go/testdata/src/coverdep/p_test.go
deleted file mode 100644
index 11a1434..0000000
--- a/libgo/go/cmd/go/testdata/src/coverdep/p_test.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package p
-
-import "testing"
-
-func Test(t *testing.T) {
-	F()
-}
diff --git a/libgo/go/cmd/go/testdata/src/coverdep2/p1/p.go b/libgo/go/cmd/go/testdata/src/coverdep2/p1/p.go
deleted file mode 100644
index fd31527..0000000
--- a/libgo/go/cmd/go/testdata/src/coverdep2/p1/p.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package p1
-
-func F() int { return 1 }
diff --git a/libgo/go/cmd/go/testdata/src/coverdep2/p1/p_test.go b/libgo/go/cmd/go/testdata/src/coverdep2/p1/p_test.go
deleted file mode 100644
index c402568..0000000
--- a/libgo/go/cmd/go/testdata/src/coverdep2/p1/p_test.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package p1_test
-
-import (
-	"coverdep2/p2"
-	"testing"
-)
-
-func Test(t *testing.T) {
-	p2.F()
-}
diff --git a/libgo/go/cmd/go/testdata/src/coverdep2/p2/p2.go b/libgo/go/cmd/go/testdata/src/coverdep2/p2/p2.go
deleted file mode 100644
index 33561bb..0000000
--- a/libgo/go/cmd/go/testdata/src/coverdep2/p2/p2.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package p2
-
-import "coverdep2/p1"
-
-func F() {
-	p1.F()
-}
diff --git a/libgo/go/cmd/go/testdata/src/coverdot1/p.go b/libgo/go/cmd/go/testdata/src/coverdot1/p.go
deleted file mode 100644
index cda364f..0000000
--- a/libgo/go/cmd/go/testdata/src/coverdot1/p.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package coverdot1
-
-func F() {}
diff --git a/libgo/go/cmd/go/testdata/src/coverdot2/p.go b/libgo/go/cmd/go/testdata/src/coverdot2/p.go
deleted file mode 100644
index 80f79ae..0000000
--- a/libgo/go/cmd/go/testdata/src/coverdot2/p.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package coverdot2
-
-import . "coverdot1"
-
-func G() { F() }
diff --git a/libgo/go/cmd/go/testdata/src/coverdot2/p_test.go b/libgo/go/cmd/go/testdata/src/coverdot2/p_test.go
deleted file mode 100644
index da66e3e..0000000
--- a/libgo/go/cmd/go/testdata/src/coverdot2/p_test.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package coverdot2
-
-import "testing"
-
-func TestG(t *testing.T) {
-	G()
-}
diff --git a/libgo/go/cmd/go/testdata/src/empty/pkg/pkg.go b/libgo/go/cmd/go/testdata/src/empty/pkg/pkg.go
deleted file mode 100644
index c89cd18..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/pkg/pkg.go
+++ /dev/null
@@ -1 +0,0 @@
-package p
diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtest/pkg.go b/libgo/go/cmd/go/testdata/src/empty/pkgtest/pkg.go
deleted file mode 100644
index c89cd18..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/pkgtest/pkg.go
+++ /dev/null
@@ -1 +0,0 @@
-package p
diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtest/test_test.go b/libgo/go/cmd/go/testdata/src/empty/pkgtest/test_test.go
deleted file mode 100644
index c89cd18..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/pkgtest/test_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package p
diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/pkg.go b/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/pkg.go
deleted file mode 100644
index c89cd18..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/pkg.go
+++ /dev/null
@@ -1 +0,0 @@
-package p
diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/test_test.go b/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/test_test.go
deleted file mode 100644
index c89cd18..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/test_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package p
diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/xtest_test.go b/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/xtest_test.go
deleted file mode 100644
index 9b64e8e..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/pkgtestxtest/xtest_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package p_test
diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgxtest/pkg.go b/libgo/go/cmd/go/testdata/src/empty/pkgxtest/pkg.go
deleted file mode 100644
index c89cd18..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/pkgxtest/pkg.go
+++ /dev/null
@@ -1 +0,0 @@
-package p
diff --git a/libgo/go/cmd/go/testdata/src/empty/pkgxtest/xtest_test.go b/libgo/go/cmd/go/testdata/src/empty/pkgxtest/xtest_test.go
deleted file mode 100644
index 9b64e8e..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/pkgxtest/xtest_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package p_test
diff --git a/libgo/go/cmd/go/testdata/src/empty/test/test_test.go b/libgo/go/cmd/go/testdata/src/empty/test/test_test.go
deleted file mode 100644
index c89cd18..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/test/test_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package p
diff --git a/libgo/go/cmd/go/testdata/src/empty/testxtest/test_test.go b/libgo/go/cmd/go/testdata/src/empty/testxtest/test_test.go
deleted file mode 100644
index c89cd18..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/testxtest/test_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package p
diff --git a/libgo/go/cmd/go/testdata/src/empty/testxtest/xtest_test.go b/libgo/go/cmd/go/testdata/src/empty/testxtest/xtest_test.go
deleted file mode 100644
index 9b64e8e..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/testxtest/xtest_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package p_test
diff --git a/libgo/go/cmd/go/testdata/src/empty/xtest/xtest_test.go b/libgo/go/cmd/go/testdata/src/empty/xtest/xtest_test.go
deleted file mode 100644
index 9b64e8e..0000000
--- a/libgo/go/cmd/go/testdata/src/empty/xtest/xtest_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package p_test
diff --git a/libgo/go/cmd/go/testdata/src/exclude/empty/x.txt b/libgo/go/cmd/go/testdata/src/exclude/empty/x.txt
deleted file mode 100644
index e69de29..0000000
--- a/libgo/go/cmd/go/testdata/src/exclude/empty/x.txt
+++ /dev/null
diff --git a/libgo/go/cmd/go/testdata/src/exclude/ignore/_x.go b/libgo/go/cmd/go/testdata/src/exclude/ignore/_x.go
deleted file mode 100644
index 823aafd..0000000
--- a/libgo/go/cmd/go/testdata/src/exclude/ignore/_x.go
+++ /dev/null
@@ -1 +0,0 @@
-package x
diff --git a/libgo/go/cmd/go/testdata/src/exclude/x.go b/libgo/go/cmd/go/testdata/src/exclude/x.go
deleted file mode 100644
index 9affd21..0000000
--- a/libgo/go/cmd/go/testdata/src/exclude/x.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// +build linux,!linux
-
-package x
diff --git a/libgo/go/cmd/go/testdata/src/exclude/x_linux.go b/libgo/go/cmd/go/testdata/src/exclude/x_linux.go
deleted file mode 100644
index 41ef6e5..0000000
--- a/libgo/go/cmd/go/testdata/src/exclude/x_linux.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// +build windows
-
-package x
diff --git a/libgo/go/cmd/go/testdata/src/failfast_test.go b/libgo/go/cmd/go/testdata/src/failfast_test.go
deleted file mode 100644
index 6e64d73..0000000
--- a/libgo/go/cmd/go/testdata/src/failfast_test.go
+++ /dev/null
@@ -1,62 +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.
-
-package failfast
-
-import "testing"
-
-func TestA(t *testing.T) {
-	// Edge-case testing, mixing unparallel tests too
-	t.Logf("LOG: %s", t.Name())
-}
-
-func TestFailingA(t *testing.T) {
-	t.Errorf("FAIL - %s", t.Name())
-}
-
-func TestB(t *testing.T) {
-	// Edge-case testing, mixing unparallel tests too
-	t.Logf("LOG: %s", t.Name())
-}
-
-func TestParallelFailingA(t *testing.T) {
-	t.Parallel()
-	t.Errorf("FAIL - %s", t.Name())
-}
-
-func TestParallelFailingB(t *testing.T) {
-	t.Parallel()
-	t.Errorf("FAIL - %s", t.Name())
-}
-
-func TestParallelFailingSubtestsA(t *testing.T) {
-	t.Parallel()
-	t.Run("TestFailingSubtestsA1", func(t *testing.T) {
-		t.Errorf("FAIL - %s", t.Name())
-	})
-	t.Run("TestFailingSubtestsA2", func(t *testing.T) {
-		t.Errorf("FAIL - %s", t.Name())
-	})
-}
-
-func TestFailingSubtestsA(t *testing.T) {
-	t.Run("TestFailingSubtestsA1", func(t *testing.T) {
-		t.Errorf("FAIL - %s", t.Name())
-	})
-	t.Run("TestFailingSubtestsA2", func(t *testing.T) {
-		t.Errorf("FAIL - %s", t.Name())
-	})
-}
-
-func TestFailingB(t *testing.T) {
-	t.Errorf("FAIL - %s", t.Name())
-}
-
-func TestFatalC(t *testing.T) {
-	t.Fatalf("FAIL - %s", t.Name())
-}
-
-func TestFatalD(t *testing.T) {
-	t.Fatalf("FAIL - %s", t.Name())
-}
diff --git a/libgo/go/cmd/go/testdata/src/hello/hello.go b/libgo/go/cmd/go/testdata/src/hello/hello.go
deleted file mode 100644
index 73d83e6..0000000
--- a/libgo/go/cmd/go/testdata/src/hello/hello.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package main
-
-func main() {
-	println("hello, world")
-}
diff --git a/libgo/go/cmd/go/testdata/src/my.pkg/main/main.go b/libgo/go/cmd/go/testdata/src/my.pkg/main/main.go
deleted file mode 100644
index c3e8de1..0000000
--- a/libgo/go/cmd/go/testdata/src/my.pkg/main/main.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package main
-