]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.boringcrypto] all: merge master into dev.boringcrypto
authorNicolas Hillegeer <aktau@google.com>
Tue, 29 Mar 2022 00:40:23 +0000 (17:40 -0700)
committerNicolas Hillegeer <aktau@google.com>
Tue, 29 Mar 2022 13:58:14 +0000 (06:58 -0700)
Change-Id: I04d511ed8e3e7ca4a3267f226a0c3e248c0f84a9

1  2 
src/cmd/compile/internal/amd64/versions_test.go
src/cmd/compile/internal/reflectdata/reflect.go
src/cmd/go/go_test.go
src/cmd/go/internal/load/pkg.go
src/cmd/link/internal/ld/lib.go
src/go/build/build.go
src/go/build/deps_test.go
src/runtime/race/testdata/mop_test.go

index a21e5f2e6f774f943fbd56c9decd4909ea585679,78e87d0ad4018f9fe5de5ebff0b4f18e23590ce9..6c2617d844e75229ef7ca1bc95f97c2e095b007e
@@@ -2,14 -2,13 +2,15 @@@
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
 +//go:build !boringcrypto
 +
  package amd64_test
  
  import (
        "bufio"
        "debug/elf"
        "debug/macho"
+       "errors"
        "fmt"
        "internal/testenv"
        "io"
@@@ -117,9 -116,12 +118,12 @@@ func clobber(t *testing.T, src string, 
                var err error
                disasm, err = cmd.StdoutPipe()
                if err != nil {
-                       t.Skipf("can't run test due to missing objdump: %s", err)
+                       t.Fatal(err)
                }
                if err := cmd.Start(); err != nil {
+                       if errors.Is(err, exec.ErrNotFound) {
+                               t.Skipf("can't run test due to missing objdump: %s", err)
+                       }
                        t.Fatal(err)
                }
                re = regexp.MustCompile(`^\s*([0-9a-f]+):\s*((?:[0-9a-f][0-9a-f] )+)\s*([a-z0-9]+)`)
index c809f4658deb1ac0ff3976111bc6e04364f13c95,c49444179edb71ca1e491c6b608150c8318732c1..633700afb079d734daa37acb333ca1902d6474a1
@@@ -1155,33 -1155,6 +1155,33 @@@ func writeType(t *types.Type) *obj.LSy
        // for security, only the exported fields.
        case types.TSTRUCT:
                fields := t.Fields().Slice()
 +
 +              // omitFieldForAwfulBoringCryptoKludge reports whether
 +              // the field t should be omitted from the reflect data.
 +              // In the crypto/... packages we omit an unexported field
 +              // named "boring", to keep from breaking client code that
 +              // expects rsa.PublicKey etc to have only public fields.
 +              // As the name suggests, this is an awful kludge, but it is
 +              // limited to the dev.boringcrypto branch and avoids
 +              // much more invasive effects elsewhere.
 +              omitFieldForAwfulBoringCryptoKludge := func(t *types.Field) bool {
 +                      if t.Sym == nil || t.Sym.Name != "boring" || t.Sym.Pkg == nil {
 +                              return false
 +                      }
 +                      path := t.Sym.Pkg.Path
 +                      if t.Sym.Pkg == types.LocalPkg {
 +                              path = base.Ctxt.Pkgpath
 +                      }
 +                      return strings.HasPrefix(path, "crypto/")
 +              }
 +              newFields := fields[:0:0]
 +              for _, t1 := range fields {
 +                      if !omitFieldForAwfulBoringCryptoKludge(t1) {
 +                              newFields = append(newFields, t1)
 +                      }
 +              }
 +              fields = newFields
 +
                for _, t1 := range fields {
                        writeType(t1.Type)
                }
                }
        }
  
-       ot = dextratypeData(lsym, ot, t)
-       objw.Global(lsym, int32(ot), int16(obj.DUPOK|obj.RODATA))
        // Note: DUPOK is required to ensure that we don't end up with more
-       // than one type descriptor for a given type.
+       // than one type descriptor for a given type, if the type descriptor
+       // can be defined in multiple packages, that is, unnamed types and
+       // instantiated types.
+       dupok := 0
+       if tbase.Sym() == nil || tbase.IsFullyInstantiated() {
+               dupok = obj.DUPOK
+       }
+       ot = dextratypeData(lsym, ot, t)
+       objw.Global(lsym, int32(ot), int16(dupok|obj.RODATA))
  
        // The linker will leave a table of all the typelinks for
        // types in the binary, so the runtime can find them.
@@@ -1846,16 -1826,17 +1853,17 @@@ func methodWrapper(rcvr *types.Type, me
  
        newnam := ir.MethodSym(rcvr, method.Sym)
        lsym := newnam.Linksym()
-       if newnam.Siggen() {
-               return lsym
-       }
-       newnam.SetSiggen(true)
  
        // Unified IR creates its own wrappers.
        if base.Debug.Unified != 0 {
                return lsym
        }
  
+       if newnam.Siggen() {
+               return lsym
+       }
+       newnam.SetSiggen(true)
        methodrcvr := method.Type.Recv().Type
        // For generic methods, we need to generate the wrapper even if the receiver
        // types are identical, because we want to add the dictionary.
  
                        // Target method uses shaped names.
                        targs2 := make([]*types.Type, len(targs))
-                       origRParams := deref(orig).OrigSym().Def.(*ir.Name).Type().RParams()
+                       origRParams := deref(orig).OrigType().RParams()
                        for i, t := range targs {
                                targs2[i] = typecheck.Shapify(t, i, origRParams[i])
                        }
diff --combined src/cmd/go/go_test.go
index 11ba733b38166eed11f9c73c42fb5cddb1acd0fb,fa0d44dae60ddc6dcaf81889f25f82b90354b8ea..84fef6db7720d2a6f5d9ae1bf059dcf767f431e2
@@@ -14,7 -14,6 +14,6 @@@ import 
        "fmt"
        "go/format"
        "internal/godebug"
-       "internal/race"
        "internal/testenv"
        "io"
        "io/fs"
        "cmd/go/internal/cache"
        "cmd/go/internal/cfg"
        "cmd/go/internal/robustio"
+       "cmd/go/internal/search"
+       "cmd/go/internal/work"
        "cmd/internal/sys"
+       cmdgo "cmd/go"
  )
  
  func init() {
@@@ -84,6 -87,43 +87,43 @@@ var testBin strin
  // The TestMain function creates a go command for testing purposes and
  // deletes it after the tests have been run.
  func TestMain(m *testing.M) {
+       // When CMDGO_TEST_RUN_MAIN is set, we're reusing the test binary as cmd/go.
+       // Enable the special behavior needed in cmd/go/internal/work,
+       // run the main func exported via export_test.go, and exit.
+       // We set CMDGO_TEST_RUN_MAIN via os.Setenv and testScript.setup.
+       if os.Getenv("CMDGO_TEST_RUN_MAIN") != "" {
+               if v := os.Getenv("TESTGO_VERSION"); v != "" {
+                       work.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.
+                       work.AllowInstall = func(a *work.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))
+                       }
+               }
+               cmdgo.Main()
+               os.Exit(0)
+       }
+       os.Setenv("CMDGO_TEST_RUN_MAIN", "true")
        // $GO_GCFLAGS a compiler debug flag known to cmd/dist, make.bash, etc.
        // It is not a standard go command flag; use os.Getenv, not cfg.Getenv.
        if os.Getenv("GO_GCFLAGS") != "" {
                        log.Fatal(err)
                }
                testGo = filepath.Join(testBin, "go"+exeSuffix)
-               args := []string{"build", "-tags", "testgo", "-o", testGo}
-               if race.Enabled {
-                       args = append(args, "-race")
-               }
                gotool, err := testenv.GoTool()
                if err != nil {
                        fmt.Fprintln(os.Stderr, "locating go tool: ", err)
                        return
                }
  
-               buildCmd := exec.Command(gotool, args...)
-               buildCmd.Env = append(os.Environ(), "GOFLAGS=-mod=vendor")
-               out, err := buildCmd.CombinedOutput()
+               // Duplicate the test executable into the path at testGo, for $PATH.
+               // If the OS supports symlinks, use them instead of copying bytes.
+               testExe, err := os.Executable()
                if err != nil {
-                       fmt.Fprintf(os.Stderr, "building testgo failed: %v\n%s", err, out)
-                       os.Exit(2)
+                       log.Fatal(err)
+               }
+               if err := os.Symlink(testExe, testGo); err != nil {
+                       // Otherwise, copy the bytes.
+                       src, err := os.Open(testExe)
+                       if err != nil {
+                               log.Fatal(err)
+                       }
+                       defer src.Close()
+                       dst, err := os.OpenFile(testGo, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o777)
+                       if err != nil {
+                               log.Fatal(err)
+                       }
+                       _, err = io.Copy(dst, src)
+                       if closeErr := dst.Close(); err == nil {
+                               err = closeErr
+                       }
+                       if err != nil {
+                               log.Fatal(err)
+                       }
                }
  
                cmd := exec.Command(testGo, "env", "CGO_ENABLED")
                        }
                }
  
-               out, err = exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
+               out, err := exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
                if err != nil {
                        fmt.Fprintf(os.Stderr, "could not find testing GOCACHE: %v\n%s", err, out)
                        os.Exit(2)
@@@ -1575,7 -1631,7 +1631,7 @@@ func TestListTemplateContextFunction(t 
        }{
                {"GOARCH", runtime.GOARCH},
                {"GOOS", runtime.GOOS},
-               {"GOROOT", filepath.Clean(runtime.GOROOT())},
+               {"GOROOT", testGOROOT},
                {"GOPATH", os.Getenv("GOPATH")},
                {"CgoEnabled", ""},
                {"UseAllFiles", ""},
@@@ -1843,12 -1899,8 +1899,12 @@@ func TestBinaryOnlyPackages(t *testing.
        tg.grepStdout("p2: false", "p2 listed as BinaryOnly")
  }
  
 -// Issue 16050.
 -func TestAlwaysLinkSysoFiles(t *testing.T) {
 +// Issue 16050 and 21884.
 +func TestLinkSysoFiles(t *testing.T) {
 +      if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
 +              t.Skip("not linux/amd64")
 +      }
 +
        tg := testgo(t)
        defer tg.cleanup()
        tg.parallel()
        tg.setenv("CGO_ENABLED", "0")
        tg.run("list", "-f", "{{.SysoFiles}}", "syso")
        tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0")
 +
 +      tg.setenv("CGO_ENABLED", "1")
 +      tg.run("list", "-msan", "-f", "{{.SysoFiles}}", "syso")
 +      tg.grepStdoutNot("a.syso", "unexpected syso file with -msan")
  }
  
  // Issue 16120.
index 1a510b86c71eb893f7f1c3452e69e6182e792b09,2592cf54477405fb2776dc7cb3b5fb3f5120cc3a..a1cfcad8267289ae52affbb25bfc332bf5fa2863
@@@ -193,6 -193,18 +193,18 @@@ func (p *Package) Desc() string 
        return p.ImportPath
  }
  
+ // IsTestOnly reports whether p is a test-only package.
+ //
+ // A “test-only” package is one that:
+ //    - is a test-only variant of an ordinary package, or
+ //    - is a synthesized "main" package for a test binary, or
+ //    - contains only _test.go files.
+ func (p *Package) IsTestOnly() bool {
+       return p.ForTest != "" ||
+               p.Internal.TestmainGo != nil ||
+               len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 && len(p.GoFiles)+len(p.CgoFiles) == 0
+ }
  type PackageInternal struct {
        // Unexported fields are not part of the public API.
        Build             *build.Package
@@@ -388,12 -400,6 +400,12 @@@ func (p *Package) copyBuild(opts Packag
        p.SwigFiles = pp.SwigFiles
        p.SwigCXXFiles = pp.SwigCXXFiles
        p.SysoFiles = pp.SysoFiles
 +      if cfg.BuildMSan {
 +              // There's no way for .syso files to be built both with and without
 +              // support for memory sanitizer. Assume they are built without,
 +              // and drop them.
 +              p.SysoFiles = nil
 +      }
        p.CgoCFLAGS = pp.CgoCFLAGS
        p.CgoCPPFLAGS = pp.CgoCPPFLAGS
        p.CgoCXXFLAGS = pp.CgoCXXFLAGS
@@@ -1932,8 -1938,12 +1944,12 @@@ func (p *Package) load(ctx context.Cont
        }
        p.Internal.Imports = imports
        p.collectDeps()
-       if p.Error == nil && p.Name == "main" && len(p.DepsErrors) == 0 {
-               p.setBuildInfo()
+       if p.Error == nil && p.Name == "main" && !p.Internal.ForceLibrary && len(p.DepsErrors) == 0 {
+               // TODO(bcmills): loading VCS metadata can be fairly slow.
+               // Consider starting this as a background goroutine and retrieving the result
+               // asynchronously when we're actually ready to build the package, or when we
+               // actually need to evaluate whether the package's metadata is stale.
+               p.setBuildInfo(opts.LoadVCS)
        }
  
        // unsafe is a fake package.
@@@ -2222,12 -2232,7 +2238,7 @@@ var vcsStatusCache par.Cach
  //
  // Note that the GoVersion field is not set here to avoid encoding it twice.
  // It is stored separately in the binary, mostly for historical reasons.
- func (p *Package) setBuildInfo() {
-       // TODO: build and vcs information is not embedded for executables in GOROOT.
-       // cmd/dist uses -gcflags=all= -ldflags=all= by default, which means these
-       // executables always appear stale unless the user sets the same flags.
-       // Perhaps it's safe to omit those flags when GO_GCFLAGS and GO_LDFLAGS
-       // are not set?
+ func (p *Package) setBuildInfo(includeVCS bool) {
        setPkgErrorf := func(format string, args ...any) {
                if p.Error == nil {
                        p.Error = &PackageError{Err: fmt.Errorf(format, args...)}
        // Add command-line flags relevant to the build.
        // This is informational, not an exhaustive list.
        // Please keep the list sorted.
-       if !p.Standard {
-               if cfg.BuildASan {
-                       appendSetting("-asan", "true")
-               }
-               if BuildAsmflags.present {
-                       appendSetting("-asmflags", BuildAsmflags.String())
-               }
-               appendSetting("-compiler", cfg.BuildContext.Compiler)
-               if BuildGccgoflags.present && cfg.BuildContext.Compiler == "gccgo" {
-                       appendSetting("-gccgoflags", BuildGccgoflags.String())
-               }
-               if BuildGcflags.present && cfg.BuildContext.Compiler == "gc" {
-                       appendSetting("-gcflags", BuildGcflags.String())
-               }
-               if BuildLdflags.present {
-                       appendSetting("-ldflags", BuildLdflags.String())
-               }
-               if cfg.BuildMSan {
-                       appendSetting("-msan", "true")
-               }
-               if cfg.BuildRace {
-                       appendSetting("-race", "true")
-               }
-               if tags := cfg.BuildContext.BuildTags; len(tags) > 0 {
-                       appendSetting("-tags", strings.Join(tags, ","))
-               }
-               cgo := "0"
-               if cfg.BuildContext.CgoEnabled {
-                       cgo = "1"
-               }
-               appendSetting("CGO_ENABLED", cgo)
-               if cfg.BuildContext.CgoEnabled {
-                       for _, name := range []string{"CGO_CFLAGS", "CGO_CPPFLAGS", "CGO_CXXFLAGS", "CGO_LDFLAGS"} {
-                               appendSetting(name, cfg.Getenv(name))
-                       }
-               }
-               appendSetting("GOARCH", cfg.BuildContext.GOARCH)
-               if cfg.GOEXPERIMENT != "" {
-                       appendSetting("GOEXPERIMENT", cfg.GOEXPERIMENT)
-               }
-               appendSetting("GOOS", cfg.BuildContext.GOOS)
-               if key, val := cfg.GetArchEnv(); key != "" && val != "" {
-                       appendSetting(key, val)
+       if cfg.BuildASan {
+               appendSetting("-asan", "true")
+       }
+       if BuildAsmflags.present {
+               appendSetting("-asmflags", BuildAsmflags.String())
+       }
+       appendSetting("-compiler", cfg.BuildContext.Compiler)
+       if gccgoflags := BuildGccgoflags.String(); gccgoflags != "" && cfg.BuildContext.Compiler == "gccgo" {
+               appendSetting("-gccgoflags", gccgoflags)
+       }
+       if gcflags := BuildGcflags.String(); gcflags != "" && cfg.BuildContext.Compiler == "gc" {
+               appendSetting("-gcflags", gcflags)
+       }
+       if ldflags := BuildLdflags.String(); ldflags != "" {
+               appendSetting("-ldflags", ldflags)
+       }
+       if cfg.BuildMSan {
+               appendSetting("-msan", "true")
+       }
+       if cfg.BuildRace {
+               appendSetting("-race", "true")
+       }
+       if tags := cfg.BuildContext.BuildTags; len(tags) > 0 {
+               appendSetting("-tags", strings.Join(tags, ","))
+       }
+       if cfg.BuildTrimpath {
+               appendSetting("-trimpath", "true")
+       }
+       cgo := "0"
+       if cfg.BuildContext.CgoEnabled {
+               cgo = "1"
+       }
+       appendSetting("CGO_ENABLED", cgo)
+       if cfg.BuildContext.CgoEnabled {
+               for _, name := range []string{"CGO_CFLAGS", "CGO_CPPFLAGS", "CGO_CXXFLAGS", "CGO_LDFLAGS"} {
+                       appendSetting(name, cfg.Getenv(name))
                }
        }
+       appendSetting("GOARCH", cfg.BuildContext.GOARCH)
+       if cfg.RawGOEXPERIMENT != "" {
+               appendSetting("GOEXPERIMENT", cfg.RawGOEXPERIMENT)
+       }
+       appendSetting("GOOS", cfg.BuildContext.GOOS)
+       if key, val := cfg.GetArchEnv(); key != "" && val != "" {
+               appendSetting(key, val)
+       }
  
        // Add VCS status if all conditions are true:
        //
        // - -buildvcs is enabled.
-       // - p is contained within a main module (there may be multiple main modules
-       //   in a workspace, but local replacements don't count).
+       // - p is a non-test contained within a main module (there may be multiple
+       //   main modules in a workspace, but local replacements don't count).
        // - Both the current directory and p's module's root directory are contained
        //   in the same local repository.
        // - We know the VCS commands needed to get the status.
        var vcsCmd *vcs.Cmd
        var err error
        const allowNesting = true
-       if cfg.BuildBuildvcs && p.Module != nil && p.Module.Version == "" && !p.Standard {
+       if includeVCS && p.Module != nil && p.Module.Version == "" && !p.Standard && !p.IsTestOnly() {
                repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "", allowNesting)
                if err != nil && !errors.Is(err, os.ErrNotExist) {
                        setVCSError(err)
@@@ -2654,6 -2660,9 +2666,9 @@@ type PackageOpts struct 
        // are not be matched, and their dependencies may not be loaded. A warning
        // may be printed for non-literal arguments that match no main packages.
        MainOnly bool
+       // LoadVCS controls whether we also load version-control metadata for main packages.
+       LoadVCS bool
  }
  
  // PackagesAndErrors returns the packages named by the command line arguments
@@@ -3007,7 -3016,7 +3022,7 @@@ func PackagesAndErrorsOutsideModule(ct
        patterns := make([]string, len(args))
        for i, arg := range args {
                if !strings.HasSuffix(arg, "@"+version) {
-                       return nil, fmt.Errorf("%s: all arguments must have the same version (@%s)", arg, version)
+                       return nil, fmt.Errorf("%s: all arguments must refer to packages in the same module at the same version (@%s)", arg, version)
                }
                p := arg[:len(arg)-len(version)-1]
                switch {
index 5b82dc287d20bd9487908e15244d341f46935c57,61b1fcbecfa3e413bb9d131348da00b9d8e35230..6055d4327ea29908618936bf5daa4a35ed703323
@@@ -390,7 -390,9 +390,9 @@@ func libinit(ctxt *Link) 
                suffix = "asan"
        }
  
-       Lflag(ctxt, filepath.Join(buildcfg.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", buildcfg.GOOS, buildcfg.GOARCH, suffixsep, suffix)))
+       if buildcfg.GOROOT != "" {
+               Lflag(ctxt, filepath.Join(buildcfg.GOROOT, "pkg", fmt.Sprintf("%s_%s%s%s", buildcfg.GOOS, buildcfg.GOARCH, suffixsep, suffix)))
+       }
  
        mayberemoveoutfile()
  
@@@ -1015,7 -1017,6 +1017,7 @@@ var hostobj []Hostob
  // These packages can use internal linking mode.
  // Others trigger external mode.
  var internalpkg = []string{
 +      "crypto/internal/boring",
        "crypto/x509",
        "net",
        "os/user",
@@@ -1478,7 -1479,7 +1480,7 @@@ func (ctxt *Link) hostlink() 
                argv = append(argv, unusedArguments)
        }
  
-       const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
+       const compressDWARF = "-Wl,--compress-debug-sections=zlib"
        if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
                argv = append(argv, compressDWARF)
        }
diff --combined src/go/build/build.go
index 4bf46a8970be3a882096aa93e0c5a9a9138730a5,df505312ce32a66f353977858eb93e096f0709e4..4ec9ed57a2b1bea1c01d198289ce6e03f3ec9e89
@@@ -35,7 -35,7 +35,7 @@@ type Context struct 
        GOARCH string // target architecture
        GOOS   string // target operating system
        GOROOT string // Go root
-       GOPATH string // Go path
+       GOPATH string // Go paths
  
        // Dir is the caller's working directory, or the empty string to use
        // the current directory of the running process. In module mode, this is used
@@@ -302,7 -302,9 +302,9 @@@ func defaultContext() Context 
  
        c.GOARCH = buildcfg.GOARCH
        c.GOOS = buildcfg.GOOS
-       c.GOROOT = pathpkg.Clean(runtime.GOROOT())
+       if goroot := runtime.GOROOT(); goroot != "" {
+               c.GOROOT = filepath.Clean(goroot)
+       }
        c.GOPATH = envOr("GOPATH", defaultGOPATH())
        c.Compiler = runtime.Compiler
  
        // 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.
-       for _, exp := range buildcfg.EnabledExperiments() {
+       for _, exp := range buildcfg.Experiment.Enabled() {
                c.ToolTags = append(c.ToolTags, "goexperiment."+exp)
        }
        defaultToolTags = append([]string{}, c.ToolTags...) // our own private copy
@@@ -672,7 -674,7 +674,7 @@@ func (ctxt *Context) Import(path string
                                }
                                return false
                        }
-                       if ctxt.Compiler != "gccgo" && searchVendor(ctxt.GOROOT, true) {
+                       if ctxt.Compiler != "gccgo" && ctxt.GOROOT != "" && searchVendor(ctxt.GOROOT, true) {
                                goto Found
                        }
                        for _, root := range gopath {
                                }
                                tried.goroot = dir
                        }
-               }
-               if ctxt.Compiler == "gccgo" && goroot.IsStandardPackage(ctxt.GOROOT, ctxt.Compiler, path) {
-                       p.Dir = ctxt.joinPath(ctxt.GOROOT, "src", path)
-                       p.Goroot = true
-                       p.Root = ctxt.GOROOT
-                       goto Found
+                       if ctxt.Compiler == "gccgo" && goroot.IsStandardPackage(ctxt.GOROOT, ctxt.Compiler, path) {
+                               p.Dir = ctxt.joinPath(ctxt.GOROOT, "src", path)
+                               p.Goroot = true
+                               p.Root = ctxt.GOROOT
+                               goto Found
+                       }
                }
                for _, root := range gopath {
                        dir := ctxt.joinPath(root, "src", path)
@@@ -1082,6 -1084,13 +1084,13 @@@ func (ctxt *Context) importGo(p *Packag
                return errNoModules
        }
  
+       // If ctxt.GOROOT is not set, we don't know which go command to invoke,
+       // and even if we did we might return packages in GOROOT that we wouldn't otherwise find
+       // (because we don't know to search in 'go env GOROOT' otherwise).
+       if ctxt.GOROOT == "" {
+               return errNoModules
+       }
        // Predict whether module aware mode is enabled by checking the value of
        // GO111MODULE and looking for a go.mod file in the source directory or
        // one of its parents. Running 'go env GOMOD' in the source directory would
        }
  
        // For efficiency, if path is a standard library package, let the usual lookup code handle it.
-       if ctxt.GOROOT != "" {
-               dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
-               if ctxt.isDir(dir) {
-                       return errNoModules
-               }
+       if dir := ctxt.joinPath(ctxt.GOROOT, "src", path); ctxt.isDir(dir) {
+               return errNoModules
        }
  
        // If GO111MODULE=auto, look to see if there is a go.mod.
                }
        }
  
-       cmd := exec.Command("go", "list", "-e", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n{{if .Error}}{{.Error}}{{end}}\n", "--", path)
+       goCmd := filepath.Join(ctxt.GOROOT, "bin", "go")
+       cmd := exec.Command(goCmd, "list", "-e", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n{{if .Error}}{{.Error}}{{end}}\n", "--", path)
  
        if ctxt.Dir != "" {
                cmd.Dir = ctxt.Dir
                "GOPATH="+ctxt.GOPATH,
                "CGO_ENABLED="+cgo,
        )
+       if cmd.Dir != "" {
+               // If possible, set PWD: if an error occurs and PWD includes a symlink, we
+               // want the error to refer to Dir, not some other name for it.
+               if abs, err := filepath.Abs(cmd.Dir); err == nil {
+                       cmd.Env = append(cmd.Env, "PWD="+abs)
+               }
+       }
  
        if err := cmd.Run(); err != nil {
                return fmt.Errorf("go/build: go list %s: %v\n%s\n", path, err, stderr.String())
@@@ -1872,7 -1886,6 +1886,7 @@@ func (ctxt *Context) eval(x constraint.
  //    cgo (if cgo is enabled)
  //    $GOOS
  //    $GOARCH
 +//    boringcrypto
  //    ctxt.Compiler
  //    linux (if GOOS = android)
  //    solaris (if GOOS = illumos)
@@@ -1900,10 -1913,9 +1914,13 @@@ func (ctxt *Context) matchTag(name stri
        if ctxt.GOOS == "ios" && name == "darwin" {
                return true
        }
+       if name == "unix" && unixOS[ctxt.GOOS] {
+               return true
+       }
 +      // Let applications know that the Go+BoringCrypto toolchain is in use.
 +      if name == "boringcrypto" {
 +              return true
 +      }
  
        // other tags
        for _, tag := range ctxt.BuildTags {
@@@ -1970,18 -1982,6 +1987,6 @@@ func (ctxt *Context) goodOSArchFile(nam
        return true
  }
  
- var knownOS = make(map[string]bool)
- var knownArch = make(map[string]bool)
- func init() {
-       for _, v := range strings.Fields(goosList) {
-               knownOS[v] = true
-       }
-       for _, v := range strings.Fields(goarchList) {
-               knownArch[v] = true
-       }
- }
  // ToolDir is the directory containing build tools.
  var ToolDir = getToolDir()
  
index 785e14cab9aae2274f69e68d80dd4fb3399b829a,5794e3d25e9db50b3230996f61145348b2a1fc94..ade6519b8d76f0be2ca9ba6056c3a4e28ae2b4b7
@@@ -212,8 -212,7 +212,7 @@@ var depsRules = 
  
        # Misc packages needing only FMT.
        FMT
-       < flag,
-         html,
+       < html,
          mime/quotedprintable,
          net/internal/socktest,
          net/url,
        < encoding/binary
        < encoding/base32, encoding/base64;
  
+       FMT, encoding < flag;
        fmt !< encoding/base32, encoding/base64;
  
        FMT, encoding/base32, encoding/base64
        go/build/constraint, go/doc, go/parser, internal/buildcfg, internal/goroot, internal/goversion
        < go/build;
  
-       DEBUG, go/build, go/types, text/scanner
-   < internal/pkgbits
-       < go/internal/gcimporter, go/internal/gccgoimporter, go/internal/srcimporter
-       < go/importer;
        # databases
        FMT
        < database/sql/internal
  
        # Bulk of the standard library must not use cgo.
        # The prohibition stops at net and os/user.
 -      C !< fmt, go/types, CRYPTO-MATH;
 +      C !< fmt, go/types;
  
        CGO, OS
        < plugin;
        NET, log
        < net/mail;
  
 -      # CRYPTO is core crypto algorithms - no cgo, fmt, net.
 -      # Unfortunately, stuck with reflect via encoding/binary.
 -      encoding/binary, golang.org/x/sys/cpu, hash
 +      NONE < crypto/internal/boring/sig;
 +      sync/atomic < crypto/internal/boring/fipstls;
 +
 +      encoding/binary, golang.org/x/sys/cpu, hash,
 +      FMT, math/big, embed,
 +      CGO, crypto/internal/boring/sig, crypto/internal/boring/fipstls
        < crypto
        < crypto/subtle
        < crypto/internal/subtle
        < crypto/ed25519/internal/edwards25519/field, golang.org/x/crypto/curve25519/internal/field
        < crypto/ed25519/internal/edwards25519
        < crypto/cipher
 +      < encoding/asn1
 +      < crypto/internal/boring
        < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4,
          crypto/sha1, crypto/sha256, crypto/sha512
 -      < CRYPTO;
 -
 -      CGO, fmt, net !< CRYPTO;
 -
 -      # CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok.
 -      CRYPTO, FMT, math/big, embed
        < crypto/rand
        < crypto/internal/randutil
        < crypto/ed25519
 -      < encoding/asn1
        < golang.org/x/crypto/cryptobyte/asn1
        < golang.org/x/crypto/cryptobyte
        < golang.org/x/crypto/curve25519
        < crypto/dsa, crypto/elliptic, crypto/rsa
        < crypto/ecdsa
 -      < CRYPTO-MATH;
 +      < CRYPTO-BORING;
  
 -      CGO, net !< CRYPTO-MATH;
 +      net !< CRYPTO-BORING;
  
        # TLS, Prince of Dependencies.
 -      CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem
 +      CRYPTO-BORING, NET, container/list, encoding/hex, encoding/pem
        < golang.org/x/crypto/internal/subtle
        < golang.org/x/crypto/chacha20
        < golang.org/x/crypto/internal/poly1305
        < crypto/x509
        < crypto/tls;
  
 +      crypto/internal/boring/sig, crypto/internal/boring/fipstls
 +      < crypto/tls/fipsonly;
 +
 +      crypto/internal/boring
 +      < crypto/boring;
 +
        # crypto-aware packages
  
 -      CRYPTO, DEBUG, go/build, go/types, text/scanner
++      CRYPTO-BORING, DEBUG, go/build, go/types, text/scanner
+       < internal/pkgbits
+       < go/internal/gcimporter, go/internal/gccgoimporter, go/internal/srcimporter
+       < go/importer;
        NET, crypto/rand, mime/quotedprintable
        < mime/multipart;
  
  
        FMT, container/heap, math/rand
        < internal/trace;
+       FMT
+       < internal/diff, internal/txtar;
  `
  
  // listStdPkgs returns the same list of packages as "go list std".
@@@ -626,21 -626,6 +630,6 @@@ func TestDependencies(t *testing.T) 
                        t.Errorf("unexpected dependency: %s imports %v", pkg, bad)
                }
        }
-       // depPath returns the path between the given from and to packages.
-       // It returns the empty string if there's no dependency path.
-       var depPath func(string, string) string
-       depPath = func(from, to string) string {
-               if sawImport[from][to] {
-                       return from + " => " + to
-               }
-               for pkg := range sawImport[from] {
-                       if p := depPath(pkg, to); p != "" {
-                               return from + " => " + p
-                       }
-               }
-               return ""
-       }
  }
  
  var buildIgnore = []byte("\n//go:build ignore")
index 94b6e58de093dd1c017b8c15b4dd4ca988a011bc,d05a443f62a7482dbecec8a8eac0200fe9b2878b..0d79091df46676abcb3ec70170cf2c5a74aaa604
@@@ -6,9 -6,9 +6,9 @@@ package race_tes
  
  import (
        "bytes"
 -      "crypto/sha1"
        "errors"
        "fmt"
 +      "hash/crc32"
        "io"
        "os"
        "runtime"
@@@ -1896,6 -1896,14 +1896,14 @@@ func TestRaceNestedStruct(t *testing.T
  }
  
  func TestRaceIssue5567(t *testing.T) {
+       testRaceRead(t, false)
+ }
+ func TestRaceIssue51618(t *testing.T) {
+       testRaceRead(t, true)
+ }
+ func testRaceRead(t *testing.T, pread bool) {
        defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
        in := make(chan []byte)
        res := make(chan error)
                var n, total int
                b := make([]byte, 17) // the race is on b buffer
                for err == nil {
-                       n, err = f.Read(b)
+                       if pread {
+                               n, err = f.ReadAt(b, int64(total))
+                       } else {
+                               n, err = f.Read(b)
+                       }
                        total += n
                        if n > 0 {
                                in <- b[:n]
                        err = nil
                }
        }()
 -      h := sha1.New()
 +      h := crc32.New(crc32.MakeTable(0x12345678))
        for b := range in {
                h.Write(b)
        }