aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/dist/build.go33
-rw-r--r--src/cmd/dist/build_test.go10
-rw-r--r--src/cmd/go/internal/work/gc.go2
-rw-r--r--src/cmd/link/internal/ld/config.go28
-rw-r--r--src/cmd/link/internal/ld/dwarf_test.go6
-rw-r--r--src/cmd/link/internal/ld/ld_test.go2
-rw-r--r--src/cmd/link/link_test.go18
-rw-r--r--src/cmd/nm/nm_cgo_test.go41
8 files changed, 53 insertions, 87 deletions
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index 444d293433..1c63c6ebc7 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -539,7 +539,36 @@ func setup() {
// mustLinkExternal is a copy of internal/platform.MustLinkExternal,
// duplicated here to avoid version skew in the MustLinkExternal function
// during bootstrapping.
-func mustLinkExternal(goos, goarch string) bool {
+func mustLinkExternal(goos, goarch string, cgoEnabled bool) bool {
+ if cgoEnabled {
+ switch goarch {
+ case "loong64",
+ "mips", "mipsle", "mips64", "mips64le",
+ "riscv64":
+ // Internally linking cgo is incomplete on some architectures.
+ // https://golang.org/issue/14449
+ return true
+ case "arm64":
+ if goos == "windows" {
+ // windows/arm64 internal linking is not implemented.
+ return true
+ }
+ case "ppc64":
+ // Big Endian PPC64 cgo internal linking is not implemented for aix or linux.
+ return true
+ }
+
+ switch goos {
+ case "android":
+ return true
+ case "dragonfly":
+ // It seems that on Dragonfly thread local storage is
+ // set up by the dynamic linker, so internal cgo linking
+ // doesn't work. Test case is "go test runtime/cgo".
+ return true
+ }
+ }
+
switch goos {
case "android":
if goarch != "arm64" {
@@ -1283,7 +1312,7 @@ func timelog(op, name string) {
// to switch between the host and target configurations when cross-compiling.
func toolenv() []string {
var env []string
- if !mustLinkExternal(goos, goarch) {
+ if !mustLinkExternal(goos, goarch, false) {
// Unless the platform requires external linking,
// we disable cgo to get static binaries for cmd/go and cmd/pprof,
// so that they work on systems without the same dynamic libraries
diff --git a/src/cmd/dist/build_test.go b/src/cmd/dist/build_test.go
index a97c4cbc32..158ac2678d 100644
--- a/src/cmd/dist/build_test.go
+++ b/src/cmd/dist/build_test.go
@@ -14,10 +14,12 @@ import (
func TestMustLinkExternal(t *testing.T) {
for _, goos := range okgoos {
for _, goarch := range okgoarch {
- got := mustLinkExternal(goos, goarch)
- want := platform.MustLinkExternal(goos, goarch)
- if got != want {
- t.Errorf("mustLinkExternal(%q, %q) = %v; want %v", goos, goarch, got, want)
+ for _, cgoEnabled := range []bool{true, false} {
+ got := mustLinkExternal(goos, goarch, cgoEnabled)
+ want := platform.MustLinkExternal(goos, goarch, cgoEnabled)
+ if got != want {
+ t.Errorf("mustLinkExternal(%q, %q, %v) = %v; want %v", goos, goarch, cgoEnabled, got, want)
+ }
}
}
}
diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go
index 3f59b6d41f..51d1760d9c 100644
--- a/src/cmd/go/internal/work/gc.go
+++ b/src/cmd/go/internal/work/gc.go
@@ -643,7 +643,7 @@ func (gcToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string)
// linker's build id, which will cause our build id to not
// match the next time the tool is built.
// Rely on the external build id instead.
- if !platform.MustLinkExternal(cfg.Goos, cfg.Goarch) {
+ if !platform.MustLinkExternal(cfg.Goos, cfg.Goarch, false) {
ldflags = append(ldflags, "-X=cmd/internal/objabi.buildID="+root.buildID)
}
}
diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go
index f2dfa1c1cd..7cce28dac5 100644
--- a/src/cmd/link/internal/ld/config.go
+++ b/src/cmd/link/internal/ld/config.go
@@ -5,7 +5,6 @@
package ld
import (
- "cmd/internal/sys"
"fmt"
"internal/buildcfg"
"internal/platform"
@@ -125,7 +124,7 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) {
}()
}
- if platform.MustLinkExternal(buildcfg.GOOS, buildcfg.GOARCH) {
+ if platform.MustLinkExternal(buildcfg.GOOS, buildcfg.GOARCH, false) {
return true, fmt.Sprintf("%s/%s requires external linking", buildcfg.GOOS, buildcfg.GOARCH)
}
@@ -137,25 +136,9 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) {
return true, "asan"
}
- // Internally linking cgo is incomplete on some architectures.
- // https://golang.org/issue/14449
- if iscgo && ctxt.Arch.InFamily(sys.Loong64, sys.MIPS64, sys.MIPS, sys.RISCV64) {
+ if iscgo && platform.MustLinkExternal(buildcfg.GOOS, buildcfg.GOARCH, true) {
return true, buildcfg.GOARCH + " does not support internal cgo"
}
- if iscgo && (buildcfg.GOOS == "android" || buildcfg.GOOS == "dragonfly") {
- // It seems that on Dragonfly thread local storage is
- // set up by the dynamic linker, so internal cgo linking
- // doesn't work. Test case is "go test runtime/cgo".
- return true, buildcfg.GOOS + " does not support internal cgo"
- }
- if iscgo && buildcfg.GOOS == "windows" && buildcfg.GOARCH == "arm64" {
- // windows/arm64 internal linking is not implemented.
- return true, buildcfg.GOOS + "/" + buildcfg.GOARCH + " does not support internal cgo"
- }
- if iscgo && ctxt.Arch == sys.ArchPPC64 {
- // Big Endian PPC64 cgo internal linking is not implemented for aix or linux.
- return true, buildcfg.GOOS + " does not support internal cgo"
- }
// Some build modes require work the internal linker cannot do (yet).
switch ctxt.BuildMode {
@@ -164,12 +147,7 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) {
case BuildModeCShared:
return true, "buildmode=c-shared"
case BuildModePIE:
- switch buildcfg.GOOS + "/" + buildcfg.GOARCH {
- case "android/arm64":
- case "linux/amd64", "linux/arm64", "linux/ppc64le":
- case "windows/386", "windows/amd64", "windows/arm", "windows/arm64":
- case "darwin/amd64", "darwin/arm64":
- default:
+ if !platform.InternalLinkPIESupported(buildcfg.GOOS, buildcfg.GOARCH) {
// Internal linking does not support TLS_IE.
return true, "buildmode=pie"
}
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index 6fac85a01d..ee3ea9d175 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -274,7 +274,7 @@ func TestSizes(t *testing.T) {
}
// External linking may bring in C symbols with unknown size. Skip.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
t.Parallel()
@@ -882,7 +882,7 @@ func TestAbstractOriginSanityIssue26237(t *testing.T) {
func TestRuntimeTypeAttrInternal(t *testing.T) {
testenv.MustHaveGoBuild(t)
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
if runtime.GOOS == "plan9" {
t.Skip("skipping on plan9; no DWARF symbol table in executables")
@@ -1165,7 +1165,7 @@ func main() {
// TODO: maybe there is some way to tell the external linker not to put
// those symbols in the executable's symbol table? Prefix the symbol name
// with "." or "L" to pretend it is a label?
- if !testenv.CanInternalLink() {
+ if !testenv.CanInternalLink(false) {
return
}
diff --git a/src/cmd/link/internal/ld/ld_test.go b/src/cmd/link/internal/ld/ld_test.go
index 314dab7d7d..22bc11eff3 100644
--- a/src/cmd/link/internal/ld/ld_test.go
+++ b/src/cmd/link/internal/ld/ld_test.go
@@ -21,7 +21,7 @@ func TestUndefinedRelocErrors(t *testing.T) {
// When external linking, symbols may be defined externally, so we allow
// undefined symbols and let external linker resolve. Skip the test.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
t.Parallel()
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index b4ef9ada17..121ef95853 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -176,19 +176,7 @@ main.x: relocation target main.zero not defined
func TestIssue33979(t *testing.T) {
testenv.MustHaveGoBuild(t)
testenv.MustHaveCGO(t)
- testenv.MustInternalLink(t)
-
- // Skip test on platforms that do not support cgo internal linking.
- switch runtime.GOARCH {
- case "loong64":
- t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
- case "mips", "mipsle", "mips64", "mips64le":
- t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
- }
- if runtime.GOOS == "aix" ||
- runtime.GOOS == "windows" && runtime.GOARCH == "arm64" {
- t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
- }
+ testenv.MustInternalLink(t, true)
t.Parallel()
@@ -751,8 +739,8 @@ func TestTrampolineCgo(t *testing.T) {
// Test internal linking mode.
- if runtime.GOARCH == "ppc64" || (runtime.GOARCH == "arm64" && runtime.GOOS == "windows") || !testenv.CanInternalLink() {
- return // internal linking cgo is not supported
+ if !testenv.CanInternalLink(true) {
+ continue
}
cmd = testenv.Command(t, testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2 -linkmode=internal", "-o", exe, src)
out, err = cmd.CombinedOutput()
diff --git a/src/cmd/nm/nm_cgo_test.go b/src/cmd/nm/nm_cgo_test.go
index 210577e6f7..face58c311 100644
--- a/src/cmd/nm/nm_cgo_test.go
+++ b/src/cmd/nm/nm_cgo_test.go
@@ -2,56 +2,25 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build cgo
-
package main
import (
- "runtime"
+ "internal/testenv"
"testing"
)
-func canInternalLink() bool {
- switch runtime.GOOS {
- case "aix":
- return false
- case "dragonfly":
- return false
- case "freebsd":
- switch runtime.GOARCH {
- case "arm64", "riscv64":
- return false
- }
- case "linux":
- switch runtime.GOARCH {
- case "arm64", "loong64", "mips64", "mips64le", "mips", "mipsle", "ppc64", "ppc64le", "riscv64":
- return false
- }
- case "openbsd":
- switch runtime.GOARCH {
- case "arm64", "mips64":
- return false
- }
- case "windows":
- switch runtime.GOARCH {
- case "arm64":
- return false
- }
- }
- return true
-}
-
func TestInternalLinkerCgoExec(t *testing.T) {
- if !canInternalLink() {
- t.Skip("skipping; internal linking is not supported")
- }
+ testenv.MustHaveCGO(t)
+ testenv.MustInternalLink(t, true)
testGoExec(t, true, false)
}
func TestExternalLinkerCgoExec(t *testing.T) {
+ testenv.MustHaveCGO(t)
testGoExec(t, true, true)
}
func TestCgoLib(t *testing.T) {
+ testenv.MustHaveCGO(t)
testGoLib(t, true)
}