// 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"
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]+)`)
// 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.
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])
}
"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() {
// 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)
}{
{"GOARCH", runtime.GOARCH},
{"GOOS", runtime.GOOS},
- {"GOROOT", filepath.Clean(runtime.GOROOT())},
+ {"GOROOT", testGOROOT},
{"GOPATH", os.Getenv("GOPATH")},
{"CgoEnabled", ""},
{"UseAllFiles", ""},
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.
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
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.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.
//
// 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)
// 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
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 {
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()
// These packages can use internal linking mode.
// Others trigger external mode.
var internalpkg = []string{
+ "crypto/internal/boring",
"crypto/x509",
"net",
"os/user",
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)
}
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
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
}
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)
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())
// cgo (if cgo is enabled)
// $GOOS
// $GOARCH
+// boringcrypto
// ctxt.Compiler
// linux (if GOOS = android)
// solaris (if GOOS = illumos)
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 {
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()
# 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".
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")
import (
"bytes"
- "crypto/sha1"
"errors"
"fmt"
+ "hash/crc32"
"io"
"os"
"runtime"
}
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)
}