]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.boringcrypto] all: merge master into dev.boringcrypto
authorRoland Shoemaker <roland@golang.org>
Wed, 18 Nov 2020 18:55:34 +0000 (10:55 -0800)
committerRoland Shoemaker <roland@golang.org>
Wed, 18 Nov 2020 18:55:34 +0000 (10:55 -0800)
Change-Id: Iba19903f0565b11c648e1fa6effc07b8f97dc322

14 files changed:
1  2 
src/cmd/compile/internal/gc/reflect.go
src/cmd/go/go_test.go
src/cmd/go/internal/load/pkg.go
src/cmd/link/internal/ld/lib.go
src/crypto/rand/rand_unix.go
src/crypto/tls/cipher_suites.go
src/crypto/tls/common.go
src/crypto/tls/handshake_client.go
src/crypto/tls/handshake_client_tls13.go
src/crypto/tls/handshake_server.go
src/crypto/tls/handshake_server_tls13.go
src/crypto/x509/verify.go
src/go/build/build.go
src/go/build/deps_test.go

index d16a00b7873bb06bb31f80206cee69ab31419b2d,21429af782eb963a7ae6e822c273689732dd56fa..c12e99e71ee8174093e833d409e07a72b7126608
@@@ -1275,9 -1275,8 +1275,8 @@@ func dtypesym(t *types.Type) *obj.LSym 
                }
                ot = dgopkgpath(lsym, ot, tpkg)
  
-               xcount := sort.Search(n, func(i int) bool { return !types.IsExported(m[i].name.Name) })
                ot = dsymptr(lsym, ot, lsym, ot+3*Widthptr+uncommonSize(t))
-               ot = duintptr(lsym, ot, uint64(xcount))
+               ot = duintptr(lsym, ot, uint64(n))
                ot = duintptr(lsym, ot, uint64(n))
                dataAdd := imethodSize() * n
                ot = dextratype(lsym, ot, t, dataAdd)
        // for security, only the exported fields.
        case 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 == localpkg {
 +                              path = myimportpath
 +                      }
 +                      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 {
                        dtypesym(t1.Type)
                }
diff --combined src/cmd/go/go_test.go
index 960020e27dcdeaa458f1a424b8cae184d6673e8c,ee0cd8e2c72947e8420be1855c8fd4e2f78242ae..38d1fe6d1dcc275f4405977139105e2a0c8d5973
@@@ -9,12 -9,14 +9,14 @@@ import 
        "debug/elf"
        "debug/macho"
        "debug/pe"
+       "encoding/binary"
        "flag"
        "fmt"
        "go/format"
        "internal/race"
        "internal/testenv"
        "io"
+       "io/fs"
        "io/ioutil"
        "log"
        "os"
        "cmd/internal/sys"
  )
  
+ func init() {
+       // GOVCS defaults to public:git|hg,private:all,
+       // which breaks many tests here - they can't use non-git, non-hg VCS at all!
+       // Change to fully permissive.
+       // The tests of the GOVCS setting itself are in ../../testdata/script/govcs.txt.
+       os.Setenv("GOVCS", "*:all")
+ }
  var (
-       canRun  = true  // whether we can run go or ./testgo
        canRace = false // whether we can run the race detector
        canCgo  = false // whether we can use cgo
        canMSan = false // whether we can run the memory sanitizer
-       exeSuffix string // ".exe" on Windows
-       skipExternal = false // skip external tests
  )
  
+ var exeSuffix string = func() string {
+       if runtime.GOOS == "windows" {
+               return ".exe"
+       }
+       return ""
+ }()
  func tooSlow(t *testing.T) {
        if testing.Short() {
                // In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders.
                if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
                        return
                }
+               t.Helper()
                t.Skip("skipping test in -short mode")
        }
  }
  
- func init() {
-       switch runtime.GOOS {
-       case "android", "js":
-               canRun = false
-       case "darwin":
-               // nothing to do
-       case "ios":
-               canRun = false
-       case "linux":
-               switch runtime.GOARCH {
-               case "arm":
-                       // many linux/arm machines are too slow to run
-                       // the full set of external tests.
-                       skipExternal = true
-               case "mips", "mipsle", "mips64", "mips64le":
-                       // Also slow.
-                       skipExternal = true
-                       if testenv.Builder() != "" {
-                               // On the builders, skip the cmd/go
-                               // tests. They're too slow and already
-                               // covered by other ports. There's
-                               // nothing os/arch specific in the
-                               // tests.
-                               canRun = false
-                       }
-               }
-       case "freebsd":
-               switch runtime.GOARCH {
-               case "arm":
-                       // many freebsd/arm machines are too slow to run
-                       // the full set of external tests.
-                       skipExternal = true
-                       canRun = false
-               }
-       case "plan9":
-               switch runtime.GOARCH {
-               case "arm":
-                       // many plan9/arm machines are too slow to run
-                       // the full set of external tests.
-                       skipExternal = true
-               }
-       case "windows":
-               exeSuffix = ".exe"
-       }
- }
  // testGOROOT is the GOROOT to use when running testgo, a cmd/go binary
  // build from this process's current GOROOT, but run from a different
  // (temp) directory.
@@@ -152,7 -119,7 +119,7 @@@ func TestMain(m *testing.M) 
        }
  
        testGOCACHE = cache.DefaultDir()
-       if canRun {
+       if testenv.HasGoBuild() {
                testBin = filepath.Join(testTmpDir, "testbin")
                if err := os.Mkdir(testBin, 0777); err != nil {
                        log.Fatal(err)
                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
+                       os.Exit(2)
                } else {
                        canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
                        if err != nil {
@@@ -323,10 -290,7 +290,7 @@@ func skipIfGccgo(t *testing.T, msg stri
  func testgo(t *testing.T) *testgoData {
        t.Helper()
        testenv.MustHaveGoBuild(t)
-       if skipExternal {
-               t.Skipf("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH)
-       }
+       testenv.SkipIfShortAndSlow(t)
  
        return &testgoData{t: t}
  }
@@@ -415,9 -379,6 +379,6 @@@ func (tg *testgoData) goTool() string 
  // returning exit status.
  func (tg *testgoData) doRun(args []string) error {
        tg.t.Helper()
-       if !canRun {
-               panic("testgoData.doRun called but canRun false")
-       }
        if tg.inParallel {
                for _, arg := range args {
                        if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") {
@@@ -813,7 -774,7 +774,7 @@@ func (tg *testgoData) cleanup() 
  func removeAll(dir string) error {
        // 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 {
+       filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
                // 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() {
@@@ -860,7 -821,7 +821,7 @@@ func TestNewReleaseRebuildsStalePackage
                srcdir := filepath.Join(testGOROOT, copydir)
                tg.tempDir(filepath.Join("goroot", copydir))
                err := filepath.Walk(srcdir,
-                       func(path string, info os.FileInfo, err error) error {
+                       func(path string, info fs.FileInfo, err error) error {
                                if err != nil {
                                        return err
                                }
@@@ -1236,6 -1197,18 +1197,18 @@@ func TestGoListExport(t *testing.T) 
        if _, err := os.Stat(file); err != nil {
                t.Fatalf("cannot find .Export result %s: %v", file, err)
        }
+       tg.run("list", "-export", "-f", "{{.BuildID}}", "strings")
+       buildID := strings.TrimSpace(tg.stdout.String())
+       if buildID == "" {
+               t.Fatalf(".BuildID with -export was empty")
+       }
+       tg.run("tool", "buildid", file)
+       toolBuildID := strings.TrimSpace(tg.stdout.String())
+       if buildID != toolBuildID {
+               t.Fatalf(".BuildID with -export %q disagrees with 'go tool buildid' %q", buildID, toolBuildID)
+       }
  }
  
  // Issue 4096. Validate the output of unsuccessful go install foo/quxx.
@@@ -1843,12 -1816,8 +1816,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.
@@@ -2026,7 -1991,7 +1999,7 @@@ func main() 
        tg.run("build", "-o", exe, "p")
  }
  
- func copyFile(src, dst string, perm os.FileMode) error {
+ func copyFile(src, dst string, perm fs.FileMode) error {
        sf, err := os.Open(src)
        if err != nil {
                return err
@@@ -2065,7 -2030,7 +2038,7 @@@ func TestBuildmodePIE(t *testing.T) 
  
        platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
        switch platform {
-       case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
+       case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x",
                "android/amd64", "android/arm", "android/arm64", "android/386",
                "freebsd/amd64",
                "windows/386", "windows/amd64", "windows/arm":
@@@ -2173,6 -2138,38 +2146,38 @@@ func testBuildmodePIE(t *testing.T, use
                if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
                        t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
                }
+               if useCgo {
+                       // Test that only one symbol is exported (#40795).
+                       // PIE binaries don´t require .edata section but unfortunately
+                       // binutils doesn´t generate a .reloc section unless there is
+                       // at least one symbol exported.
+                       // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
+                       section := f.Section(".edata")
+                       if section == nil {
+                               t.Fatalf(".edata section is not present")
+                       }
+                       // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
+                       type IMAGE_EXPORT_DIRECTORY struct {
+                               _                 [2]uint32
+                               _                 [2]uint16
+                               _                 [2]uint32
+                               NumberOfFunctions uint32
+                               NumberOfNames     uint32
+                               _                 [3]uint32
+                       }
+                       var e IMAGE_EXPORT_DIRECTORY
+                       if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil {
+                               t.Fatalf("binary.Read failed: %v", err)
+                       }
+                       // Only _cgo_dummy_export should be exported
+                       if e.NumberOfFunctions != 1 {
+                               t.Fatalf("got %d exported functions; want 1", e.NumberOfFunctions)
+                       }
+                       if e.NumberOfNames != 1 {
+                               t.Fatalf("got %d exported names; want 1", e.NumberOfNames)
+                       }
+               }
        default:
                panic("unreachable")
        }
index 4b4e16c394a1b61b0342a74a307a6b6433a8e90b,30ca33b663340f379194bbe1fb23ec80d8e539b6..61b2167621bf24106dddbcfe4a58c613ec857cd1
@@@ -14,8 -14,10 +14,10 @@@ import 
        "go/build"
        "go/scanner"
        "go/token"
+       "io/fs"
        "io/ioutil"
        "os"
+       "path"
        pathpkg "path"
        "path/filepath"
        "runtime"
@@@ -27,6 -29,7 +29,7 @@@
  
        "cmd/go/internal/base"
        "cmd/go/internal/cfg"
+       "cmd/go/internal/fsys"
        "cmd/go/internal/modinfo"
        "cmd/go/internal/modload"
        "cmd/go/internal/par"
@@@ -59,6 -62,7 +62,7 @@@ type PackagePublic struct 
        ConflictDir   string                `json:",omitempty"` // Dir is hidden by this other directory
        ForTest       string                `json:",omitempty"` // package is only for use in named test
        Export        string                `json:",omitempty"` // file containing export data (set by go list -export)
+       BuildID       string                `json:",omitempty"` // build ID of the compiled package (set by go list -export)
        Module        *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any
        Match         []string              `json:",omitempty"` // command-line patterns matching this package
        Goroot        bool                  `json:",omitempty"` // is this package found in the Go root?
        SwigCXXFiles      []string `json:",omitempty"` // .swigcxx files
        SysoFiles         []string `json:",omitempty"` // .syso system object files added to package
  
+       // Embedded files
+       EmbedPatterns []string `json:",omitempty"` // //go:embed patterns
+       EmbedFiles    []string `json:",omitempty"` // files and directories matched by EmbedPatterns
        // Cgo directives
        CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler
        CgoCPPFLAGS  []string `json:",omitempty"` // cgo: flags for C preprocessor
        // Test information
        // If you add to this list you MUST add to p.AllFiles (below) too.
        // Otherwise file name security lists will not apply to any new additions.
-       TestGoFiles  []string `json:",omitempty"` // _test.go files in package
-       TestImports  []string `json:",omitempty"` // imports from TestGoFiles
-       XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
-       XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
+       TestGoFiles        []string `json:",omitempty"` // _test.go files in package
+       TestImports        []string `json:",omitempty"` // imports from TestGoFiles
+       TestEmbedPatterns  []string `json:",omitempty"` // //go:embed patterns
+       TestEmbedFiles     []string `json:",omitempty"` // //files matched by EmbedPatterns
+       XTestGoFiles       []string `json:",omitempty"` // _test.go files outside package
+       XTestImports       []string `json:",omitempty"` // imports from XTestGoFiles
+       XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns
+       XTestEmbedFiles    []string `json:",omitempty"` // //files matched by EmbedPatterns
  }
  
  // AllFiles returns the names of all the files considered for the package.
  // The go/build package filtered others out (like foo_wrongGOARCH.s)
  // and that's OK.
  func (p *Package) AllFiles() []string {
-       return str.StringList(
+       files := str.StringList(
                p.GoFiles,
                p.CgoFiles,
                // no p.CompiledGoFiles, because they are from GoFiles or generated by us
                p.TestGoFiles,
                p.XTestGoFiles,
        )
+       // EmbedFiles may overlap with the other files.
+       // Dedup, but delay building the map as long as possible.
+       // Only files in the current directory (no slash in name)
+       // need to be checked against the files variable above.
+       var have map[string]bool
+       for _, file := range p.EmbedFiles {
+               if !strings.Contains(file, "/") {
+                       if have == nil {
+                               have = make(map[string]bool)
+                               for _, file := range files {
+                                       have[file] = true
+                               }
+                       }
+                       if have[file] {
+                               continue
+                       }
+               }
+               files = append(files, file)
+       }
+       return files
  }
  
  // Desc returns the package "description", for use in b.showOutput.
@@@ -171,6 -204,7 +204,7 @@@ type PackageInternal struct 
        GobinSubdir       bool                 // install target would be subdir of GOBIN
        BuildInfo         string               // add this info to package main
        TestmainGo        *[]byte              // content for _testmain.go
+       Embed             map[string][]string  // //go:embed comment mapping
  
        Asmflags   []string // -asmflags for this package
        Gcflags    []string // -gcflags for this package
@@@ -251,8 -285,8 +285,8 @@@ func (p *Package) setLoadPackageDataErr
        // package's source files themselves (scanner errors).
        //
        // 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
+       // (including modload.ImportMissingError, ImportMissingSumError, 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
@@@ -343,12 -377,6 +377,12 @@@ func (p *Package) copyBuild(pp *build.P
        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
                p.TestImports = nil
                p.XTestImports = nil
        }
+       p.EmbedPatterns = pp.EmbedPatterns
+       p.TestEmbedPatterns = pp.TestEmbedPatterns
+       p.XTestEmbedPatterns = pp.XTestEmbedPatterns
  }
  
  // A PackageError describes an error loading information about a package.
@@@ -433,6 -464,7 +470,7 @@@ type ImportPathError interface 
  var (
        _ ImportPathError = (*importError)(nil)
        _ ImportPathError = (*modload.ImportMissingError)(nil)
+       _ ImportPathError = (*modload.ImportMissingSumError)(nil)
  )
  
  type importError struct {
@@@ -962,6 -994,12 +1000,12 @@@ func (pre *preload) preloadImports(impo
  // loadPackageData have completed. The preloader will not make any new calls
  // to loadPackageData.
  func (pre *preload) flush() {
+       // flush is usually deferred.
+       // Don't hang program waiting for workers on panic.
+       if v := recover(); v != nil {
+               panic(v)
+       }
        close(pre.cancel)
        for i := 0; i < preloadWorkerCount; i++ {
                pre.sema <- struct{}{}
@@@ -981,7 -1019,7 +1025,7 @@@ var isDirCache par.Cach
  
  func isDir(path string) bool {
        return isDirCache.Do(path, func() interface{} {
-               fi, err := os.Stat(path)
+               fi, err := fsys.Stat(path)
                return err == nil && fi.IsDir()
        }).(bool)
  }
@@@ -1626,6 -1664,11 +1670,11 @@@ func (p *Package) load(ctx context.Cont
                p.setLoadPackageDataError(err, path, stk, importPos)
        }
  
+       p.EmbedFiles, p.Internal.Embed, err = p.resolveEmbed(p.EmbedPatterns)
+       if err != nil {
+               setError(err)
+       }
        useBindir := p.Name == "main"
        if !p.Standard {
                switch cfg.BuildBuildmode {
        }
  }
  
+ // ResolveEmbed resolves //go:embed patterns and returns only the file list.
+ // For use by go list to compute p.TestEmbedFiles and p.XTestEmbedFiles.
+ func (p *Package) ResolveEmbed(patterns []string) []string {
+       files, _, _ := p.resolveEmbed(patterns)
+       return files
+ }
+ // resolveEmbed resolves //go:embed patterns to precise file lists.
+ // It sets files to the list of unique files matched (for go list),
+ // and it sets pmap to the more precise mapping from
+ // patterns to files.
+ // TODO(rsc): All these messages need position information for better error reports.
+ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[string][]string, err error) {
+       pmap = make(map[string][]string)
+       have := make(map[string]int)
+       dirOK := make(map[string]bool)
+       pid := 0 // pattern ID, to allow reuse of have map
+       for _, pattern := range patterns {
+               pid++
+               // Check pattern is valid for //go:embed.
+               if _, err := path.Match(pattern, ""); err != nil || !validEmbedPattern(pattern) {
+                       return nil, nil, fmt.Errorf("pattern %s: invalid pattern syntax", pattern)
+               }
+               // Glob to find matches.
+               match, err := fsys.Glob(p.Dir + string(filepath.Separator) + filepath.FromSlash(pattern))
+               if err != nil {
+                       return nil, nil, fmt.Errorf("pattern %s: %v", pattern, err)
+               }
+               // Filter list of matches down to the ones that will still exist when
+               // the directory is packaged up as a module. (If p.Dir is in the module cache,
+               // only those files exist already, but if p.Dir is in the current module,
+               // then there may be other things lying around, like symbolic links or .git directories.)
+               var list []string
+               for _, file := range match {
+                       rel := filepath.ToSlash(file[len(p.Dir)+1:]) // file, relative to p.Dir
+                       what := "file"
+                       info, err := fsys.Lstat(file)
+                       if err != nil {
+                               return nil, nil, err
+                       }
+                       if info.IsDir() {
+                               what = "directory"
+                       }
+                       // Check that directories along path do not begin a new module
+                       // (do not contain a go.mod).
+                       for dir := file; len(dir) > len(p.Dir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
+                               if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil {
+                                       return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in different module", pattern, what, rel)
+                               }
+                               if dir != file {
+                                       if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() {
+                                               return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in non-directory %s", pattern, what, rel, dir[len(p.Dir)+1:])
+                                       }
+                               }
+                               dirOK[dir] = true
+                               if elem := filepath.Base(dir); isBadEmbedName(elem) {
+                                       if dir == file {
+                                               return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: invalid name %s", pattern, what, rel, elem)
+                                       } else {
+                                               return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in invalid directory %s", pattern, what, rel, elem)
+                                       }
+                               }
+                       }
+                       switch {
+                       default:
+                               return nil, nil, fmt.Errorf("pattern %s: cannot embed irregular file %s", pattern, rel)
+                       case info.Mode().IsRegular():
+                               if have[rel] != pid {
+                                       have[rel] = pid
+                                       list = append(list, rel)
+                               }
+                       case info.IsDir():
+                               // Gather all files in the named directory, stopping at module boundaries
+                               // and ignoring files that wouldn't be packaged into a module.
+                               count := 0
+                               err := fsys.Walk(file, func(path string, info os.FileInfo, err error) error {
+                                       if err != nil {
+                                               return err
+                                       }
+                                       rel := filepath.ToSlash(path[len(p.Dir)+1:])
+                                       if info.IsDir() {
+                                               if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil {
+                                                       return filepath.SkipDir
+                                               }
+                                               return nil
+                                       }
+                                       if !info.Mode().IsRegular() {
+                                               return nil
+                                       }
+                                       if isBadEmbedName(info.Name()) {
+                                               // Ignore bad names, assuming they won't go into modules.
+                                               return nil
+                                       }
+                                       count++
+                                       if have[rel] != pid {
+                                               have[rel] = pid
+                                               list = append(list, rel)
+                                       }
+                                       return nil
+                               })
+                               if err != nil {
+                                       return nil, nil, err
+                               }
+                               if count == 0 {
+                                       return nil, nil, fmt.Errorf("pattern %s: cannot embed directory %s: contains no embeddable files", pattern, rel)
+                               }
+                       }
+               }
+               if len(list) == 0 {
+                       return nil, nil, fmt.Errorf("pattern %s: no matching files found", pattern)
+               }
+               sort.Strings(list)
+               pmap[pattern] = list
+       }
+       for file := range have {
+               files = append(files, file)
+       }
+       sort.Strings(files)
+       return files, pmap, nil
+ }
+ func validEmbedPattern(pattern string) bool {
+       return pattern != "." && fs.ValidPath(pattern)
+ }
+ // isBadEmbedName reports whether name is the base name of a file that
+ // can't or won't be included in modules and therefore shouldn't be treated
+ // as existing for embedding.
+ func isBadEmbedName(name string) bool {
+       switch name {
+       // Version control directories won't be present in module.
+       case ".bzr", ".hg", ".git", ".svn":
+               return true
+       }
+       return false
+ }
  // collectDeps populates p.Deps and p.DepsErrors by iterating over
  // p.Internal.Imports.
  //
@@@ -1964,10 -2154,8 +2160,8 @@@ func externalLinkingForced(p *Package) 
                if cfg.BuildContext.GOARCH != "arm64" {
                        return true
                }
-       case "darwin", "ios":
-               if cfg.BuildContext.GOARCH == "arm64" {
-                       return true
-               }
+       case "ios":
+               return true
        }
  
        // Currently build modes c-shared, pie (on systems that do not
        // external linking mode, as of course does
        // -ldflags=-linkmode=external. External linking mode forces
        // an import of runtime/cgo.
+       // If there are multiple -linkmode options, the last one wins.
        pieCgo := cfg.BuildBuildmode == "pie" && !sys.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH)
        linkmodeExternal := false
        if p != nil {
                ldflags := BuildLdflags.For(p)
-               for i, a := range ldflags {
-                       if a == "-linkmode=external" {
-                               linkmodeExternal = true
-                       }
-                       if a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
+               for i := len(ldflags) - 1; i >= 0; i-- {
+                       a := ldflags[i]
+                       if a == "-linkmode=external" ||
+                               a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
                                linkmodeExternal = true
+                               break
+                       } else if a == "-linkmode=internal" ||
+                               a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "internal" {
+                               break
                        }
                }
        }
@@@ -2149,7 -2341,7 +2347,7 @@@ func PackagesAndErrors(ctx context.Cont
                if strings.HasSuffix(p, ".go") {
                        // We need to test whether the path is an actual Go file and not a
                        // package path or pattern ending in '.go' (see golang.org/issue/34653).
-                       if fi, err := os.Stat(p); err == nil && !fi.IsDir() {
+                       if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() {
                                return []*Package{GoFilesPackage(ctx, patterns)}
                        }
                }
@@@ -2306,10 -2498,10 +2504,10 @@@ func GoFilesPackage(ctx context.Context
        // to make it look like this is a standard package or
        // command directory. So that local imports resolve
        // consistently, the files must all be in the same directory.
-       var dirent []os.FileInfo
+       var dirent []fs.FileInfo
        var dir string
        for _, file := range gofiles {
-               fi, err := os.Stat(file)
+               fi, err := fsys.Stat(file)
                if err != nil {
                        base.Fatalf("%s", err)
                }
                }
                dirent = append(dirent, fi)
        }
-       ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
+       ctxt.ReadDir = func(string) ([]fs.FileInfo, error) { return dirent, nil }
  
        if cfg.ModulesEnabled {
                modload.ImportFromFiles(ctx, gofiles)
index 99b157c56449ce7b85b6365344438ad1e4da40af,735b84d37d35c4397fe96645261cc8bb0e1211c1..4ad03e373c4eb16855d2eea29a217a4aa9c43506
@@@ -1011,7 -1011,6 +1011,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",
@@@ -1321,9 -1320,6 +1321,6 @@@ func (ctxt *Link) hostlink() 
                case objabi.Hdarwin, objabi.Haix:
                case objabi.Hwindows:
                        argv = addASLRargs(argv)
-                       // Work around binutils limitation that strips relocation table for dynamicbase.
-                       // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
-                       argv = append(argv, "-Wl,--export-all-symbols")
                default:
                        // ELF.
                        if ctxt.UseRelro() {
  
        if combineDwarf {
                dsym := filepath.Join(*flagTmpdir, "go.dwarf")
-               if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
+               if out, err := exec.Command("xcrun", "dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
                        Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
                }
                // Remove STAB (symbolic debugging) symbols after we are done with them (by dsymutil).
                // They contain temporary file paths and make the build not reproducible.
-               if out, err := exec.Command("strip", "-S", *flagOutfile).CombinedOutput(); err != nil {
+               if out, err := exec.Command("xcrun", "strip", "-S", *flagOutfile).CombinedOutput(); err != nil {
                        Exitf("%s: running strip failed: %v\n%s", os.Args[0], err, out)
                }
                // Skip combining if `dsymutil` didn't generate a file. See #11994.
@@@ -1771,12 -1767,12 +1768,12 @@@ func ldobj(ctxt *Link, f *bio.Reader, l
        magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
        if magic == 0x7f454c46 { // \x7F E L F
                ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
-                       textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.flags)
+                       textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.Flags)
                        if err != nil {
                                Errorf(nil, "%v", err)
                                return
                        }
-                       ehdr.flags = flags
+                       ehdr.Flags = flags
                        ctxt.Textp = append(ctxt.Textp, textp...)
                }
                return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file)
@@@ -2521,12 -2517,12 +2518,12 @@@ func AddGotSym(target *Target, ldr *loa
                if target.Arch.PtrSize == 8 {
                        rela := ldr.MakeSymbolUpdater(syms.Rela)
                        rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
-                       rela.AddUint64(target.Arch, ELF64_R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp))
+                       rela.AddUint64(target.Arch, elf.R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp))
                        rela.AddUint64(target.Arch, 0)
                } else {
                        rel := ldr.MakeSymbolUpdater(syms.Rel)
                        rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
-                       rel.AddUint32(target.Arch, ELF32_R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp))
+                       rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), elfRelocTyp))
                }
        } else if target.IsDarwin() {
                leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT)
index 2bd77f327f5f2758383fcabdf6a36124a920c232,548a5e4cb9a4d3d97c85d8459199324bd14443ce..8bc4abf40c69b5e3c9e5b03fd09ad3b9a36c5d18
@@@ -22,18 -22,12 +22,18 @@@ import 
        "time"
  )
  
 +import "crypto/internal/boring"
 +
  const urandomDevice = "/dev/urandom"
  
  // Easy implementation: read from /dev/urandom.
  // This is sufficient on Linux, OS X, and FreeBSD.
  
  func init() {
 +      if boring.Enabled {
 +              Reader = boring.RandReader
 +              return
 +      }
        if runtime.GOOS == "plan9" {
                Reader = newReader(nil)
        } else {
@@@ -53,8 -47,11 +53,12 @@@ type devReader struct 
  // urandom-style randomness.
  var altGetRandom func([]byte) (ok bool)
  
+ func warnBlocked() {
+       println("crypto/rand: blocked for 60 seconds waiting to read random data from the kernel")
+ }
  func (r *devReader) Read(b []byte) (n int, err error) {
 +      boring.Unreachable()
        if atomic.CompareAndSwapInt32(&r.used, 0, 1) {
                // First use of randomness. Start timer to warn about
                // being blocked on entropy not being available.
@@@ -124,7 -121,6 +128,7 @@@ type reader struct 
  }
  
  func (r *reader) Read(b []byte) (n int, err error) {
 +      boring.Unreachable()
        r.mu.Lock()
        defer r.mu.Unlock()
        n = len(b)
index cbe14f8dbd79094bcd9ca16239d383eb98210a82,9a356758fbfc5dc09835bc6db3c1cee86983f5f1..6596562fb13ecfa8f7aeec0455a48775e6392f39
@@@ -4,8 -4,6 +4,8 @@@
  
  package tls
  
 +import "crypto/internal/boring"
 +
  import (
        "crypto"
        "crypto/aes"
@@@ -162,7 -160,7 +162,7 @@@ type cipherSuite struct 
        // flags is a bitmask of the suite* values, above.
        flags  int
        cipher func(key, iv []byte, isRead bool) interface{}
-       mac    func(version uint16, macKey []byte) macFunction
+       mac    func(key []byte) hash.Hash
        aead   func(key, fixedNonce []byte) aead
  }
  
@@@ -249,30 -247,15 +249,21 @@@ func cipherAES(key, iv []byte, isRead b
        return cipher.NewCBCEncrypter(block, iv)
  }
  
- // macSHA1 returns a macFunction for the given protocol version.
- func macSHA1(version uint16, key []byte) macFunction {
+ // macSHA1 returns a SHA-1 based constant time MAC.
+ func macSHA1(key []byte) hash.Hash {
 -      return hmac.New(newConstantTimeHash(sha1.New), key)
 +      h := sha1.New
 +      // The BoringCrypto SHA1 does not have a constant-time
 +      // checksum function, so don't try to use it.
 +      if !boring.Enabled {
 +              h = newConstantTimeHash(h)
 +      }
-       return tls10MAC{h: hmac.New(h, key)}
++      return hmac.New(h, key)
  }
  
- // macSHA256 returns a SHA-256 based MAC. These are only supported in TLS 1.2
- // so the given version is ignored.
- func macSHA256(version uint16, key []byte) macFunction {
-       return tls10MAC{h: hmac.New(sha256.New, key)}
- }
- type macFunction interface {
-       // Size returns the length of the MAC.
-       Size() int
-       // MAC appends the MAC of (seq, header, data) to out. The extra data is fed
-       // into the MAC after obtaining the result to normalize timing. The result
-       // is only valid until the next invocation of MAC as the buffer is reused.
-       MAC(seq, header, data, extra []byte) []byte
+ // macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and
+ // is currently only used in disabled-by-default cipher suites.
+ func macSHA256(key []byte) hash.Hash {
+       return hmac.New(sha256.New, key)
  }
  
  type aead interface {
@@@ -346,10 -329,6 +337,10 @@@ func (f *xorNonceAEAD) Open(out, nonce
        return result, err
  }
  
 +type gcmtls interface {
 +      NewGCMTLS() (cipher.AEAD, error)
 +}
 +
  func aeadAESGCM(key, noncePrefix []byte) aead {
        if len(noncePrefix) != noncePrefixLength {
                panic("tls: internal error: wrong nonce length")
        if err != nil {
                panic(err)
        }
 -      aead, err := cipher.NewGCM(aes)
 +      var aead cipher.AEAD
 +      if aesTLS, ok := aes.(gcmtls); ok {
 +              aead, err = aesTLS.NewGCMTLS()
 +      } else {
 +              boring.Unreachable()
 +              aead, err = cipher.NewGCM(aes)
 +      }
        if err != nil {
                panic(err)
        }
@@@ -424,33 -397,20 +415,21 @@@ func (c *cthWrapper) Write(p []byte) (i
  func (c *cthWrapper) Sum(b []byte) []byte         { return c.h.ConstantTimeSum(b) }
  
  func newConstantTimeHash(h func() hash.Hash) func() hash.Hash {
 +      boring.Unreachable()
        return func() hash.Hash {
                return &cthWrapper{h().(constantTimeHash)}
        }
  }
  
  // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3.
- type tls10MAC struct {
-       h   hash.Hash
-       buf []byte
- }
- func (s tls10MAC) Size() int {
-       return s.h.Size()
- }
- // MAC is guaranteed to take constant time, as long as
- // len(seq)+len(header)+len(data)+len(extra) is constant. extra is not fed into
- // the MAC, but is only provided to make the timing profile constant.
- func (s tls10MAC) MAC(seq, header, data, extra []byte) []byte {
-       s.h.Reset()
-       s.h.Write(seq)
-       s.h.Write(header)
-       s.h.Write(data)
-       res := s.h.Sum(s.buf[:0])
+ func tls10MAC(h hash.Hash, out, seq, header, data, extra []byte) []byte {
+       h.Reset()
+       h.Write(seq)
+       h.Write(header)
+       h.Write(data)
+       res := h.Sum(out)
        if extra != nil {
-               s.h.Write(extra)
+               h.Write(extra)
        }
        return res
  }
diff --combined src/crypto/tls/common.go
index 5dd586a3aaafafe052497e6869ebd6258e111508,1370d26fe2cdf2e097b18a029f0852e961033e19..7a009949c88ed5a7089fa5a98e385180bf8bc6db
@@@ -7,6 -7,7 +7,7 @@@ package tl
  import (
        "bytes"
        "container/list"
+       "context"
        "crypto"
        "crypto/ecdsa"
        "crypto/ed25519"
@@@ -171,11 -172,11 +172,11 @@@ const 
  // hash function associated with the Ed25519 signature scheme.
  var directSigning crypto.Hash = 0
  
 -// supportedSignatureAlgorithms contains the signature and hash algorithms that
 +// defaultSupportedSignatureAlgorithms contains the signature and hash algorithms that
  // the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+
  // CertificateRequest. The two fields are merged to match with TLS 1.3.
  // Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.
 -var supportedSignatureAlgorithms = []SignatureScheme{
 +var defaultSupportedSignatureAlgorithms = []SignatureScheme{
        PSSWithSHA256,
        ECDSAWithP256AndSHA256,
        Ed25519,
@@@ -294,10 -295,26 +295,26 @@@ func (cs *ConnectionState) ExportKeying
  type ClientAuthType int
  
  const (
+       // NoClientCert indicates that no client certificate should be requested
+       // during the handshake, and if any certificates are sent they will not
+       // be verified.
        NoClientCert ClientAuthType = iota
+       // RequestClientCert indicates that a client certificate should be requested
+       // during the handshake, but does not require that the client send any
+       // certificates.
        RequestClientCert
+       // RequireAnyClientCert indicates that a client certificate should be requested
+       // during the handshake, and that at least one certificate is required to be
+       // sent by the client, but that certificate is not required to be valid.
        RequireAnyClientCert
+       // VerifyClientCertIfGiven indicates that a client certificate should be requested
+       // during the handshake, but does not require that the client sends a
+       // certificate. If the client does send a certificate it is required to be
+       // valid.
        VerifyClientCertIfGiven
+       // RequireAndVerifyClientCert indicates that a client certificate should be requested
+       // during the handshake, and that at least one valid certificate is required
+       // to be sent by the client.
        RequireAndVerifyClientCert
  )
  
@@@ -428,6 -445,16 +445,16 @@@ type ClientHelloInfo struct 
        // config is embedded by the GetCertificate or GetConfigForClient caller,
        // for use with SupportsCertificate.
        config *Config
+       // ctx is the context of the handshake that is in progress.
+       ctx context.Context
+ }
+ // Context returns the context of the handshake that is in progress.
+ // This context is a child of the context passed to HandshakeContext,
+ // if any, and is canceled when the handshake concludes.
+ func (c *ClientHelloInfo) Context() context.Context {
+       return c.ctx
  }
  
  // CertificateRequestInfo contains information from a server's
@@@ -446,6 -473,16 +473,16 @@@ type CertificateRequestInfo struct 
  
        // Version is the TLS version that was negotiated for this connection.
        Version uint16
+       // ctx is the context of the handshake that is in progress.
+       ctx context.Context
+ }
+ // Context returns the context of the handshake that is in progress.
+ // This context is a child of the context passed to HandshakeContext,
+ // if any, and is canceled when the handshake concludes.
+ func (c *CertificateRequestInfo) Context() context.Context {
+       return c.ctx
  }
  
  // RenegotiationSupport enumerates the different levels of support for TLS
@@@ -910,9 -947,6 +947,9 @@@ func (c *Config) time() time.Time 
  }
  
  func (c *Config) cipherSuites() []uint16 {
 +      if needFIPS() {
 +              return fipsCipherSuites(c)
 +      }
        s := c.CipherSuites
        if s == nil {
                s = defaultCipherSuites()
@@@ -930,9 -964,6 +967,9 @@@ var supportedVersions = []uint16
  func (c *Config) supportedVersions() []uint16 {
        versions := make([]uint16, 0, len(supportedVersions))
        for _, v := range supportedVersions {
 +              if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) {
 +                      continue
 +              }
                if c != nil && c.MinVersion != 0 && v < c.MinVersion {
                        continue
                }
@@@ -969,9 -1000,6 +1006,9 @@@ func supportedVersionsFromMax(maxVersio
  var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}
  
  func (c *Config) curvePreferences() []CurveID {
 +      if needFIPS() {
 +              return fipsCurvePreferences(c)
 +      }
        if c == nil || len(c.CurvePreferences) == 0 {
                return defaultCurvePreferences
        }
@@@ -1256,7 -1284,9 +1293,9 @@@ func (c *Config) BuildNameToCertificate
                if err != nil {
                        continue
                }
-               if len(x509Cert.Subject.CommonName) > 0 {
+               // If SANs are *not* present, some clients will consider the certificate
+               // valid for the name in the Common Name.
+               if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 {
                        c.NameToCertificate[x509Cert.Subject.CommonName] = cert
                }
                for _, san := range x509Cert.DNSNames {
@@@ -1441,8 -1471,7 +1480,8 @@@ func initDefaultCipherSuites() 
                hasGCMAsm = hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X
        )
  
 -      if hasGCMAsm {
 +      if hasGCMAsm || boringEnabled {
 +              // If BoringCrypto is enabled, always prioritize AES-GCM.
                // If AES-GCM hardware is provided then prioritise AES-GCM
                // cipher suites.
                topCipherSuites = []uint16{
index e089762b9f9a635ef396fde94afa808075d64bcc,123df7b07a096143c841da84754cdfaec41cc3f7..6d32a72fd33eb14e9308dd3f889867e6714026f1
@@@ -6,6 -6,7 +6,7 @@@ package tl
  
  import (
        "bytes"
+       "context"
        "crypto"
        "crypto/ecdsa"
        "crypto/ed25519"
@@@ -14,6 -15,7 +15,7 @@@
        "crypto/x509"
        "errors"
        "fmt"
+       "hash"
        "io"
        "net"
        "strings"
@@@ -23,6 -25,7 +25,7 @@@
  
  type clientHandshakeState struct {
        c            *Conn
+       ctx          context.Context
        serverHello  *serverHelloMsg
        hello        *clientHelloMsg
        suite        *cipherSuite
@@@ -112,10 -115,7 +115,10 @@@ func (c *Conn) makeClientHello() (*clie
        }
  
        if hello.vers >= VersionTLS12 {
 -              hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms
 +              hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
 +      }
 +      if testingOnlyForceClientHelloSignatureAlgorithms != nil {
 +              hello.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
        }
  
        var params ecdheParameters
        return hello, params, nil
  }
  
- func (c *Conn) clientHandshake() (err error) {
+ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
        if c.config == nil {
                c.config = defaultConfig()
        }
        if c.vers == VersionTLS13 {
                hs := &clientHandshakeStateTLS13{
                        c:           c,
+                       ctx:         ctx,
                        serverHello: serverHello,
                        hello:       hello,
                        ecdheParams: ecdheParams,
  
        hs := &clientHandshakeState{
                c:           c,
+               ctx:         ctx,
                serverHello: serverHello,
                hello:       hello,
                session:     session,
@@@ -542,7 -544,7 +547,7 @@@ func (hs *clientHandshakeState) doFullH
                certRequested = true
                hs.finishedHash.Write(certReq.marshal())
  
-               cri := certificateRequestInfoFromMsg(c.vers, certReq)
+               cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
                if chainToSend, err = c.getClientCertificate(cri); err != nil {
                        c.sendAlert(alertInternalError)
                        return err
@@@ -650,12 -652,12 +655,12 @@@ func (hs *clientHandshakeState) establi
        clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
                keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
        var clientCipher, serverCipher interface{}
-       var clientHash, serverHash macFunction
+       var clientHash, serverHash hash.Hash
        if hs.suite.cipher != nil {
                clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
-               clientHash = hs.suite.mac(c.vers, clientMAC)
+               clientHash = hs.suite.mac(clientMAC)
                serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
-               serverHash = hs.suite.mac(c.vers, serverMAC)
+               serverHash = hs.suite.mac(serverMAC)
        } else {
                clientCipher = hs.suite.aead(clientKey, clientIV)
                serverCipher = hs.suite.aead(serverKey, serverIV)
@@@ -837,8 -839,6 +842,8 @@@ func (c *Conn) verifyServerCertificate(
  
        if !c.config.InsecureSkipVerify {
                opts := x509.VerifyOptions{
 +                      IsBoring: isBoringCertificate,
 +
                        Roots:         c.config.RootCAs,
                        CurrentTime:   c.config.time(),
                        DNSName:       c.config.ServerName,
  
  // certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
  // <= 1.2 CertificateRequest, making an effort to fill in missing information.
- func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
+ func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
        cri := &CertificateRequestInfo{
                AcceptableCAs: certReq.certificateAuthorities,
                Version:       vers,
+               ctx:           ctx,
        }
  
        var rsaAvail, ecAvail bool
index fab26b246a04bdd02bba88b6fdcc7967dbe7348d,0e4b38003527cb29a3778f2854cfca97f5355ded..7a6ef04e7899159acf8ecdeb88a0807650fe6de6
@@@ -6,6 -6,7 +6,7 @@@ package tl
  
  import (
        "bytes"
+       "context"
        "crypto"
        "crypto/hmac"
        "crypto/rsa"
@@@ -17,6 -18,7 +18,7 @@@
  
  type clientHandshakeStateTLS13 struct {
        c           *Conn
+       ctx         context.Context
        serverHello *serverHelloMsg
        hello       *clientHelloMsg
        ecdheParams ecdheParameters
  func (hs *clientHandshakeStateTLS13) handshake() error {
        c := hs.c
  
 +      if needFIPS() {
 +              return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
 +      }
 +
        // The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
        // sections 4.1.2 and 4.1.3.
        if c.handshakes > 0 {
@@@ -472,7 -470,7 +474,7 @@@ func (hs *clientHandshakeStateTLS13) re
        }
  
        // See RFC 8446, Section 4.4.3.
 -      if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) {
 +      if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
                c.sendAlert(alertIllegalParameter)
                return errors.New("tls: certificate used with invalid signature algorithm")
        }
@@@ -553,6 -551,7 +555,7 @@@ func (hs *clientHandshakeStateTLS13) se
                AcceptableCAs:    hs.certReq.certificateAuthorities,
                SignatureSchemes: hs.certReq.supportedSignatureAlgorithms,
                Version:          c.vers,
+               ctx:              hs.ctx,
        })
        if err != nil {
                return err
index 99e30b884566d4ad3ef1930cce5ae4cad2ae8a55,73df19d10f5dbc2a853c6c45f20f745144568287..17abe0f4d5cb44dc44c26a1a07c57adccf5a7a5e
@@@ -5,6 -5,7 +5,7 @@@
  package tls
  
  import (
+       "context"
        "crypto"
        "crypto/ecdsa"
        "crypto/ed25519"
@@@ -13,6 -14,7 +14,7 @@@
        "crypto/x509"
        "errors"
        "fmt"
+       "hash"
        "io"
        "sync/atomic"
        "time"
@@@ -22,6 -24,7 +24,7 @@@
  // It's discarded once the handshake has completed.
  type serverHandshakeState struct {
        c            *Conn
+       ctx          context.Context
        clientHello  *clientHelloMsg
        hello        *serverHelloMsg
        suite        *cipherSuite
@@@ -36,8 -39,8 +39,8 @@@
  }
  
  // serverHandshake performs a TLS handshake as a server.
- func (c *Conn) serverHandshake() error {
-       clientHello, err := c.readClientHello()
+ func (c *Conn) serverHandshake(ctx context.Context) error {
+       clientHello, err := c.readClientHello(ctx)
        if err != nil {
                return err
        }
@@@ -45,6 -48,7 +48,7 @@@
        if c.vers == VersionTLS13 {
                hs := serverHandshakeStateTLS13{
                        c:           c,
+                       ctx:         ctx,
                        clientHello: clientHello,
                }
                return hs.handshake()
@@@ -52,6 -56,7 +56,7 @@@
  
        hs := serverHandshakeState{
                c:           c,
+               ctx:         ctx,
                clientHello: clientHello,
        }
        return hs.handshake()
@@@ -123,7 -128,7 +128,7 @@@ func (hs *serverHandshakeState) handsha
  }
  
  // readClientHello reads a ClientHello message and selects the protocol version.
- func (c *Conn) readClientHello() (*clientHelloMsg, error) {
+ func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
        msg, err := c.readHandshake()
        if err != nil {
                return nil, err
        var configForClient *Config
        originalConfig := c.config
        if c.config.GetConfigForClient != nil {
-               chi := clientHelloInfo(c, clientHello)
+               chi := clientHelloInfo(ctx, c, clientHello)
                if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
                        c.sendAlert(alertInternalError)
                        return nil, err
@@@ -219,7 -224,7 +224,7 @@@ func (hs *serverHandshakeState) process
                }
        }
  
-       hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
+       hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
        if err != nil {
                if err == errNoCertificates {
                        c.sendAlert(alertUnrecognizedName)
@@@ -500,7 -505,7 +505,7 @@@ func (hs *serverHandshakeState) doFullH
                }
                if c.vers >= VersionTLS12 {
                        certReq.hasSignatureAlgorithm = true
 -                      certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms
 +                      certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
                }
  
                // An empty list of certificateAuthorities signals to
@@@ -641,13 -646,13 +646,13 @@@ func (hs *serverHandshakeState) establi
                keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  
        var clientCipher, serverCipher interface{}
-       var clientHash, serverHash macFunction
+       var clientHash, serverHash hash.Hash
  
        if hs.suite.aead == nil {
                clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
-               clientHash = hs.suite.mac(c.vers, clientMAC)
+               clientHash = hs.suite.mac(clientMAC)
                serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
-               serverHash = hs.suite.mac(c.vers, serverMAC)
+               serverHash = hs.suite.mac(serverMAC)
        } else {
                clientCipher = hs.suite.aead(clientKey, clientIV)
                serverCipher = hs.suite.aead(serverKey, serverIV)
@@@ -771,8 -776,6 +776,8 @@@ func (c *Conn) processCertsFromClient(c
  
        if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
                opts := x509.VerifyOptions{
 +                      IsBoring: isBoringCertificate,
 +
                        Roots:         c.config.ClientCAs,
                        CurrentTime:   c.config.time(),
                        Intermediates: x509.NewCertPool(),
        return nil
  }
  
- func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
+ func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
        supportedVersions := clientHello.supportedVersions
        if len(clientHello.supportedVersions) == 0 {
                supportedVersions = supportedVersionsFromMax(clientHello.vers)
                SupportedVersions: supportedVersions,
                Conn:              c.conn,
                config:            c.config,
+               ctx:               ctx,
        }
  }
index 7a84efd2a9c52ff884643697fa56d4ba278ea187,25c37b92c54674cb3a293c561dcd3424f3e9db9b..222d63418c0998f9ee39e9ceeac49756e837c047
@@@ -6,6 -6,7 +6,7 @@@ package tl
  
  import (
        "bytes"
+       "context"
        "crypto"
        "crypto/hmac"
        "crypto/rsa"
@@@ -23,6 -24,7 +24,7 @@@ const maxClientPSKIdentities = 
  
  type serverHandshakeStateTLS13 struct {
        c               *Conn
+       ctx             context.Context
        clientHello     *clientHelloMsg
        hello           *serverHelloMsg
        sentDummyCCS    bool
  func (hs *serverHandshakeStateTLS13) handshake() error {
        c := hs.c
  
 +      if needFIPS() {
 +              return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
 +      }
 +
        // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
        if err := hs.processClientHello(); err != nil {
                return err
@@@ -365,7 -363,7 +367,7 @@@ func (hs *serverHandshakeStateTLS13) pi
                return c.sendAlert(alertMissingExtension)
        }
  
-       certificate, err := c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
+       certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
        if err != nil {
                if err == errNoCertificates {
                        c.sendAlert(alertUnrecognizedName)
@@@ -588,7 -586,7 +590,7 @@@ func (hs *serverHandshakeStateTLS13) se
                certReq := new(certificateRequestMsgTLS13)
                certReq.ocspStapling = true
                certReq.scts = true
 -              certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms
 +              certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
                if c.config.ClientCAs != nil {
                        certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
                }
@@@ -807,7 -805,7 +809,7 @@@ func (hs *serverHandshakeStateTLS13) re
                }
  
                // See RFC 8446, Section 4.4.3.
 -              if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) {
 +              if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
                        c.sendAlert(alertIllegalParameter)
                        return errors.New("tls: client certificate used with invalid signature algorithm")
                }
index 50f4d4ac807821dbf81907ca11e1d4588b516a95,46afb2698a919ddb64131ee9d5df0958f2063309..3e343dd531c2b0dfd1cf37b4c758ae1fb6f2ccc1
@@@ -187,17 -187,14 +187,19 @@@ func (se SystemRootsError) Error() stri
        return msg
  }
  
+ func (se SystemRootsError) Unwrap() error { return se.Err }
  // errNotParsed is returned when a certificate without ASN.1 contents is
  // verified. Platform-specific verification needs the ASN.1 contents.
  var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate")
  
  // VerifyOptions contains parameters for Certificate.Verify.
  type VerifyOptions struct {
 +      // IsBoring is a validity check for BoringCrypto.
 +      // If not nil, it will be called to check whether a given certificate
 +      // can be used for constructing verification chains.
 +      IsBoring func(*Certificate) bool
 +
        // DNSName, if set, is checked against the leaf certificate with
        // Certificate.VerifyHostname or the platform verifier.
        DNSName string
@@@ -728,13 -725,6 +730,13 @@@ func (c *Certificate) isValid(certType 
                }
        }
  
 +      if opts.IsBoring != nil && !opts.IsBoring(c) {
 +              // IncompatibleUsage is not quite right here,
 +              // but it's also the "no chains found" error
 +              // and is close enough.
 +              return CertificateInvalidError{c, IncompatibleUsage, ""}
 +      }
 +
        return nil
  }
  
@@@ -771,11 -761,13 +773,13 @@@ func (c *Certificate) Verify(opts Verif
        if len(c.Raw) == 0 {
                return nil, errNotParsed
        }
-       if opts.Intermediates != nil {
-               for _, intermediate := range opts.Intermediates.certs {
-                       if len(intermediate.Raw) == 0 {
-                               return nil, errNotParsed
-                       }
+       for i := 0; i < opts.Intermediates.len(); i++ {
+               c, err := opts.Intermediates.cert(i)
+               if err != nil {
+                       return nil, fmt.Errorf("crypto/x509: error fetching intermediate: %w", err)
+               }
+               if len(c.Raw) == 0 {
+                       return nil, errNotParsed
                }
        }
  
@@@ -901,11 -893,11 +905,11 @@@ func (c *Certificate) buildChains(cach
                }
        }
  
-       for _, rootNum := range opts.Roots.findPotentialParents(c) {
-               considerCandidate(rootCertificate, opts.Roots.certs[rootNum])
+       for _, root := range opts.Roots.findPotentialParents(c) {
+               considerCandidate(rootCertificate, root)
        }
-       for _, intermediateNum := range opts.Intermediates.findPotentialParents(c) {
-               considerCandidate(intermediateCertificate, opts.Intermediates.certs[intermediateNum])
+       for _, intermediate := range opts.Intermediates.findPotentialParents(c) {
+               considerCandidate(intermediateCertificate, intermediate)
        }
  
        if len(chains) > 0 {
diff --combined src/go/build/build.go
index 55eaa3bea2df761113ab38e5a8d45101c0d3282d,82e481bdc212f85f50939e68900fcc083fb36ddd..7783cad0dd4e544cdb6a7e51903ccc5347a91815
@@@ -10,11 -10,11 +10,11 @@@ import 
        "fmt"
        "go/ast"
        "go/doc"
-       "go/parser"
        "go/token"
        "internal/goroot"
        "internal/goversion"
        "io"
+       "io/fs"
        "io/ioutil"
        "os"
        "os/exec"
@@@ -98,10 -98,10 +98,10 @@@ type Context struct 
        // filepath.EvalSymlinks.
        HasSubdir func(root, dir string) (rel string, ok bool)
  
-       // ReadDir returns a slice of os.FileInfo, sorted by Name,
+       // ReadDir returns a slice of fs.FileInfo, sorted by Name,
        // describing the content of the named directory.
        // If ReadDir is nil, Import uses ioutil.ReadDir.
-       ReadDir func(dir string) ([]os.FileInfo, error)
+       ReadDir func(dir string) ([]fs.FileInfo, error)
  
        // OpenFile opens a file (not a directory) for reading.
        // If OpenFile is nil, Import uses os.Open.
@@@ -183,7 -183,7 +183,7 @@@ func hasSubdir(root, dir string) (rel s
  }
  
  // readDir calls ctxt.ReadDir (if not nil) or else ioutil.ReadDir.
- func (ctxt *Context) readDir(path string) ([]os.FileInfo, error) {
+ func (ctxt *Context) readDir(path string) ([]fs.FileInfo, error) {
        if f := ctxt.ReadDir; f != nil {
                return f(path)
        }
@@@ -432,17 -432,26 +432,26 @@@ type Package struct 
        CgoLDFLAGS   []string // Cgo LDFLAGS directives
        CgoPkgConfig []string // Cgo pkg-config directives
  
-       // Dependency information
-       Imports   []string                    // import paths from GoFiles, CgoFiles
-       ImportPos map[string][]token.Position // line information for Imports
        // Test information
-       TestGoFiles    []string                    // _test.go files in package
+       TestGoFiles  []string // _test.go files in package
+       XTestGoFiles []string // _test.go files outside package
+       // Dependency information
+       Imports        []string                    // import paths from GoFiles, CgoFiles
+       ImportPos      map[string][]token.Position // line information for Imports
        TestImports    []string                    // import paths from TestGoFiles
        TestImportPos  map[string][]token.Position // line information for TestImports
-       XTestGoFiles   []string                    // _test.go files outside package
        XTestImports   []string                    // import paths from XTestGoFiles
        XTestImportPos map[string][]token.Position // line information for XTestImports
+       // //go:embed patterns found in Go source files
+       // For example, if a source file says
+       //      //go:embed a* b.c
+       // then the list will contain those two strings as separate entries.
+       // (See package embed for more details about //go:embed.)
+       EmbedPatterns      []string // patterns from GoFiles, CgoFiles
+       TestEmbedPatterns  []string // patterns from TestGoFiles
+       XTestEmbedPatterns []string // patterns from XTestGoFiles
  }
  
  // IsCommand reports whether the package is considered a
@@@ -785,6 -794,7 +794,7 @@@ Found
        var badGoError error
        var Sfiles []string // files with ".S"(capital S)/.sx(capital s equivalent for case insensitive filesystems)
        var firstFile, firstCommentFile string
+       var embeds, testEmbeds, xTestEmbeds []string
        imported := make(map[string][]token.Position)
        testImported := make(map[string][]token.Position)
        xTestImported := make(map[string][]token.Position)
                if d.IsDir() {
                        continue
                }
-               if (d.Mode() & os.ModeSymlink) != 0 {
-                       if fi, err := os.Stat(filepath.Join(p.Dir, d.Name())); err == nil && fi.IsDir() {
+               if d.Mode()&fs.ModeSymlink != 0 {
+                       if ctxt.isDir(ctxt.joinPath(p.Dir, d.Name())) {
                                // Symlinks to directories are not source files.
                                continue
                        }
                        p.InvalidGoFiles = append(p.InvalidGoFiles, name)
                }
  
-               match, data, filename, err := ctxt.matchFile(p.Dir, name, allTags, &p.BinaryOnly)
+               info, err := ctxt.matchFile(p.Dir, name, allTags, &p.BinaryOnly, fset)
                if err != nil {
                        badFile(err)
                        continue
                }
-               if !match {
+               if info == nil {
                        if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") {
                                // not due to build constraints - don't report
                        } else if ext == ".go" {
                        }
                        continue
                }
+               data, filename := info.header, info.name
  
                // Going to save the file. For non-Go files, can stop here.
                switch ext {
                        continue
                }
  
-               pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
-               if err != nil {
-                       badFile(err)
+               if info.parseErr != nil {
+                       badFile(info.parseErr)
                        continue
                }
+               pf := info.parsed
  
                pkg := pf.Name.Name
                if pkg == "documentation" {
                }
  
                // Record imports and information about cgo.
-               type importPos struct {
-                       path string
-                       pos  token.Pos
-               }
-               var fileImports []importPos
                isCgo := false
-               for _, decl := range pf.Decls {
-                       d, ok := decl.(*ast.GenDecl)
-                       if !ok {
-                               continue
-                       }
-                       for _, dspec := range d.Specs {
-                               spec, ok := dspec.(*ast.ImportSpec)
-                               if !ok {
+               for _, imp := range info.imports {
+                       if imp.path == "C" {
+                               if isTest {
+                                       badFile(fmt.Errorf("use of cgo in test %s not supported", filename))
                                        continue
                                }
-                               quoted := spec.Path.Value
-                               path, err := strconv.Unquote(quoted)
-                               if err != nil {
-                                       panic(fmt.Sprintf("%s: parser returned invalid quoted string: <%s>", filename, quoted))
-                               }
-                               fileImports = append(fileImports, importPos{path, spec.Pos()})
-                               if path == "C" {
-                                       if isTest {
-                                               badFile(fmt.Errorf("use of cgo in test %s not supported", filename))
-                                       } else {
-                                               cg := spec.Doc
-                                               if cg == nil && len(d.Specs) == 1 {
-                                                       cg = d.Doc
-                                               }
-                                               if cg != nil {
-                                                       if err := ctxt.saveCgo(filename, p, cg); err != nil {
-                                                               badFile(err)
-                                                       }
-                                               }
-                                               isCgo = true
+                               isCgo = true
+                               if imp.doc != nil {
+                                       if err := ctxt.saveCgo(filename, p, imp.doc); err != nil {
+                                               badFile(err)
                                        }
                                }
                        }
                }
  
-               var fileList *[]string
+               var fileList, embedList *[]string
                var importMap map[string][]token.Position
                switch {
                case isCgo:
                        if ctxt.CgoEnabled {
                                fileList = &p.CgoFiles
                                importMap = imported
+                               embedList = &embeds
                        } else {
                                // Ignore imports from cgo files if cgo is disabled.
                                fileList = &p.IgnoredGoFiles
                case isXTest:
                        fileList = &p.XTestGoFiles
                        importMap = xTestImported
+                       embedList = &xTestEmbeds
                case isTest:
                        fileList = &p.TestGoFiles
                        importMap = testImported
+                       embedList = &testEmbeds
                default:
                        fileList = &p.GoFiles
                        importMap = imported
+                       embedList = &embeds
                }
                *fileList = append(*fileList, name)
                if importMap != nil {
-                       for _, imp := range fileImports {
+                       for _, imp := range info.imports {
                                importMap[imp.path] = append(importMap[imp.path], fset.Position(imp.pos))
                        }
                }
+               if embedList != nil {
+                       *embedList = append(*embedList, info.embeds...)
+               }
        }
  
        for tag := range allTags {
        }
        sort.Strings(p.AllTags)
  
+       p.EmbedPatterns = uniq(embeds)
+       p.TestEmbedPatterns = uniq(testEmbeds)
+       p.XTestEmbedPatterns = uniq(xTestEmbeds)
        p.Imports, p.ImportPos = cleanImports(imported)
        p.TestImports, p.TestImportPos = cleanImports(testImported)
        p.XTestImports, p.XTestImportPos = cleanImports(xTestImported)
@@@ -1017,6 -1014,22 +1014,22 @@@ func fileListForExt(p *Package, ext str
        return nil
  }
  
+ func uniq(list []string) []string {
+       if list == nil {
+               return nil
+       }
+       out := make([]string, len(list))
+       copy(out, list)
+       sort.Strings(out)
+       uniq := out[:0]
+       for _, x := range out {
+               if len(uniq) == 0 || uniq[len(uniq)-1] != x {
+                       uniq = append(uniq, x)
+               }
+       }
+       return uniq
+ }
  var errNoModules = errors.New("not using modules")
  
  // importGo checks whether it can use the go command to find the directory for path.
@@@ -1104,9 -1117,14 +1117,14 @@@ func (ctxt *Context) importGo(p *Packag
                        }
                }
                for {
-                       info, err := os.Stat(filepath.Join(parent, "go.mod"))
-                       if err == nil && !info.IsDir() {
-                               break
+                       if f, err := ctxt.openFile(ctxt.joinPath(parent, "go.mod")); err == nil {
+                               buf := make([]byte, 100)
+                               _, err := f.Read(buf)
+                               f.Close()
+                               if err == nil || err == io.EOF {
+                                       // go.mod exists and is readable (is a file, not a directory).
+                                       break
+                               }
                        }
                        d := filepath.Dir(parent)
                        if len(d) >= len(parent) {
@@@ -1308,24 -1326,46 +1326,46 @@@ func parseWord(data []byte) (word, res
  // MatchFile considers the name of the file and may use ctxt.OpenFile to
  // read some or all of the file's content.
  func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) {
-       match, _, _, err = ctxt.matchFile(dir, name, nil, nil)
-       return
+       info, err := ctxt.matchFile(dir, name, nil, nil, nil)
+       return info != nil, err
  }
  
  var dummyPkg Package
  
+ // fileInfo records information learned about a file included in a build.
+ type fileInfo struct {
+       name     string // full name including dir
+       header   []byte
+       fset     *token.FileSet
+       parsed   *ast.File
+       parseErr error
+       imports  []fileImport
+       embeds   []string
+       embedErr error
+ }
+ type fileImport struct {
+       path string
+       pos  token.Pos
+       doc  *ast.CommentGroup
+ }
  // matchFile determines whether the file with the given name in the given directory
  // should be included in the package being constructed.
- // It returns the data read from the file.
+ // If the file should be included, matchFile returns a non-nil *fileInfo (and a nil error).
+ // Non-nil errors are reserved for unexpected problems.
+ //
  // If name denotes a Go program, matchFile reads until the end of the
- // imports (and returns that data) even though it only considers text
- // until the first non-comment.
+ // imports and returns that section of the file in the fileInfo's header field,
+ // even though it only considers text until the first non-comment
+ // for +build lines.
+ //
  // If allTags is non-nil, matchFile records any encountered build tag
  // by setting allTags[tag] = true.
- func (ctxt *Context) matchFile(dir, name string, allTags map[string]bool, binaryOnly *bool) (match bool, data []byte, filename string, err error) {
+ func (ctxt *Context) matchFile(dir, name string, allTags map[string]bool, binaryOnly *bool, fset *token.FileSet) (*fileInfo, error) {
        if strings.HasPrefix(name, "_") ||
                strings.HasPrefix(name, ".") {
-               return
+               return nil, nil
        }
  
        i := strings.LastIndex(name, ".")
        ext := name[i:]
  
        if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
-               return
+               return nil, nil
        }
  
        if ext != ".go" && fileListForExt(&dummyPkg, ext) == nil {
                // skip
-               return
+               return nil, nil
        }
  
+       info := &fileInfo{name: ctxt.joinPath(dir, name), fset: fset}
        if ext == ".syso" {
                // binary, no reading
-               match = true
-               return
+               return info, nil
        }
  
-       filename = ctxt.joinPath(dir, name)
-       f, err := ctxt.openFile(filename)
+       f, err := ctxt.openFile(info.name)
        if err != nil {
-               return
+               return nil, err
        }
  
-       if strings.HasSuffix(filename, ".go") {
-               data, err = readImports(f, false, nil)
-               if strings.HasSuffix(filename, "_test.go") {
+       if strings.HasSuffix(name, ".go") {
+               err = readGoInfo(f, info)
+               if strings.HasSuffix(name, "_test.go") {
                        binaryOnly = nil // ignore //go:binary-only-package comments in _test.go files
                }
        } else {
                binaryOnly = nil // ignore //go:binary-only-package comments in non-Go sources
-               data, err = readComments(f)
+               info.header, err = readComments(f)
        }
        f.Close()
        if err != nil {
-               err = fmt.Errorf("read %s: %v", filename, err)
-               return
+               return nil, fmt.Errorf("read %s: %v", info.name, err)
        }
  
        // Look for +build comments to accept or reject the file.
-       ok, sawBinaryOnly, err := ctxt.shouldBuild(data, allTags)
+       ok, sawBinaryOnly, err := ctxt.shouldBuild(info.header, allTags)
        if err != nil {
-               return // non-nil err
+               return nil, err
        }
        if !ok && !ctxt.UseAllFiles {
-               return // nil err
+               return nil, nil
        }
  
        if binaryOnly != nil && sawBinaryOnly {
                *binaryOnly = true
        }
-       match = true
-       return
+       return info, nil
  }
  
  func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) {
@@@ -1787,7 -1825,6 +1825,7 @@@ func splitQuoted(s string) (r []string
  //    $GOARCH
  //    cgo (if cgo is enabled)
  //    !cgo (if cgo is disabled)
 +//    boringcrypto
  //    ctxt.Compiler
  //    !ctxt.Compiler
  //    tag (if tag is listed in ctxt.BuildTags or ctxt.ReleaseTags)
@@@ -1842,10 -1879,6 +1880,10 @@@ func (ctxt *Context) match(name string
        if ctxt.GOOS == "ios" && name == "darwin" {
                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 {
index 775be8799adab02292aeb1d7fed06415a8ca37e9,b26b2bd199c4f742114863db184aee56dfb2e6fa..3a0726a293ea5daa86a1afed1c038330f8fa4236
@@@ -11,12 -11,12 +11,12 @@@ import 
        "bytes"
        "fmt"
        "internal/testenv"
+       "io/fs"
        "io/ioutil"
        "os"
        "path/filepath"
        "runtime"
        "sort"
-       "strconv"
        "strings"
        "testing"
  )
@@@ -122,7 -122,7 +122,7 @@@ var depsRules = 
        < context
        < TIME;
  
-       TIME, io, sort
+       TIME, io, path, sort
        < io/fs;
  
        # MATH is RUNTIME plus the basic math packages.
        MATH
        < math/rand;
  
+       MATH
+       < runtime/metrics;
        MATH, unicode/utf8
        < strconv;
  
  
        os/signal, STR
        < path/filepath
-       < io/ioutil, os/exec
+       < io/ioutil, os/exec;
+       io/ioutil, os/exec, os/signal
        < OS;
  
        reflect !< OS;
  
        # 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,
 +      CGO, crypto/internal/boring/sig, crypto/internal/boring/fipstls
        < crypto
        < crypto/subtle
        < crypto/internal/subtle
        < 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
        < crypto/rand
        < crypto/internal/randutil
        < crypto/ed25519/internal/edwards25519
        < 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.
 -      CGO, CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem
 +      CGO, CRYPTO-BORING, NET, container/list, encoding/hex, encoding/pem
        < golang.org/x/crypto/internal/subtle
        < golang.org/x/crypto/chacha20
        < golang.org/x/crypto/poly1305
        < crypto/x509
        < crypto/tls;
  
 +      crypto/internal/boring/sig, crypto/internal/boring/fipstls
 +      < crypto/tls/fipsonly;
 +
 +      crypto/internal/boring
 +      < crypto/boring;
 +
        # crypto-aware packages
  
        NET, crypto/rand, mime/quotedprintable
        < net/rpc
        < net/rpc/jsonrpc;
  
+       # System Information
+       internal/cpu, sync
+       < internal/sysinfo;
        # Test-only
        log
-       < testing/iotest;
+       < testing/iotest
+       < testing/fstest;
  
        FMT, flag, math/rand
        < testing/quick;
  
-       FMT, flag, runtime/debug, runtime/trace
+       FMT, flag, runtime/debug, runtime/trace, internal/sysinfo
        < testing;
  
        internal/testlog, runtime/pprof, regexp
@@@ -504,7 -510,7 +514,7 @@@ func listStdPkgs(goroot string) ([]stri
        var pkgs []string
  
        src := filepath.Join(goroot, "src") + string(filepath.Separator)
-       walkFn := func(path string, fi os.FileInfo, err error) error {
+       walkFn := func(path string, fi fs.FileInfo, err error) error {
                if err != nil || !fi.IsDir() || path == src {
                        return nil
                }
@@@ -606,24 -612,22 +616,22 @@@ func findImports(pkg string) ([]string
                if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
                        continue
                }
-               f, err := os.Open(filepath.Join(dir, name))
+               var info fileInfo
+               info.name = filepath.Join(dir, name)
+               f, err := os.Open(info.name)
                if err != nil {
                        return nil, err
                }
-               var imp []string
-               data, err := readImports(f, false, &imp)
+               err = readGoInfo(f, &info)
                f.Close()
                if err != nil {
                        return nil, fmt.Errorf("reading %v: %v", name, err)
                }
-               if bytes.Contains(data, buildIgnore) {
+               if bytes.Contains(info.header, buildIgnore) {
                        continue
                }
-               for _, quoted := range imp {
-                       path, err := strconv.Unquote(quoted)
-                       if err != nil {
-                               continue
-                       }
+               for _, imp := range info.imports {
+                       path := imp.path
                        if !haveImport[path] {
                                haveImport[path] = true
                                imports = append(imports, path)