aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
-rw-r--r--src/internal/platform/supported.go41
-rw-r--r--src/internal/testenv/testenv.go11
-rw-r--r--src/os/exec/exec_test.go2
-rw-r--r--src/runtime/crash_test.go14
-rw-r--r--src/runtime/time_test.go2
13 files changed, 105 insertions, 105 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)
}
diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go
index 71bf1c5477..8bf68a6d58 100644
--- a/src/internal/platform/supported.go
+++ b/src/internal/platform/supported.go
@@ -71,8 +71,39 @@ func FuzzInstrumented(goos, goarch string) bool {
}
}
-// MustLinkExternal reports whether goos/goarch requires external linking.
-func MustLinkExternal(goos, goarch string) bool {
+// MustLinkExternal reports whether goos/goarch requires external linking
+// with or without cgo dependencies.
+func MustLinkExternal(goos, goarch string, withCgo bool) bool {
+ if withCgo {
+ switch goarch {
+ case "loong64",
+ "mips", "mipsle", "mips64", "mips64le",
+ "riscv64":
+ // Internally linking cgo is incomplete on some architectures.
+ // https://go.dev/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.
+ // https://go.dev/issue/8912
+ 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" {
@@ -178,10 +209,10 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool {
func InternalLinkPIESupported(goos, goarch string) bool {
switch goos + "/" + goarch {
- case "darwin/amd64", "darwin/arm64",
+ case "android/arm64",
+ "darwin/amd64", "darwin/arm64",
"linux/amd64", "linux/arm64", "linux/ppc64le",
- "android/arm64",
- "windows-amd64", "windows-386", "windows-arm":
+ "windows/386", "windows/amd64", "windows/arm", "windows/arm64":
return true
}
return false
diff --git a/src/internal/testenv/testenv.go b/src/internal/testenv/testenv.go
index 65a82fd5f7..816a1a100f 100644
--- a/src/internal/testenv/testenv.go
+++ b/src/internal/testenv/testenv.go
@@ -288,15 +288,18 @@ func MustHaveCGO(t testing.TB) {
// CanInternalLink reports whether the current system can link programs with
// internal linking.
-func CanInternalLink() bool {
- return !platform.MustLinkExternal(runtime.GOOS, runtime.GOARCH)
+func CanInternalLink(withCgo bool) bool {
+ return !platform.MustLinkExternal(runtime.GOOS, runtime.GOARCH, withCgo)
}
// MustInternalLink checks that the current system can link programs with internal
// linking.
// If not, MustInternalLink calls t.Skip with an explanation.
-func MustInternalLink(t testing.TB) {
- if !CanInternalLink() {
+func MustInternalLink(t testing.TB, withCgo bool) {
+ if !CanInternalLink(withCgo) {
+ if withCgo && CanInternalLink(false) {
+ t.Skipf("skipping test: internal linking on %s/%s is not supported with cgo", runtime.GOOS, runtime.GOARCH)
+ }
t.Skipf("skipping test: internal linking on %s/%s is not supported", runtime.GOOS, runtime.GOARCH)
}
}
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
index 9f9cb598d8..67cd446f42 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -694,7 +694,7 @@ func TestExtraFiles(t *testing.T) {
// This test runs with cgo disabled. External linking needs cgo, so
// it doesn't work if external linking is required.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
if runtime.GOOS == "windows" {
t.Skipf("skipping test on %q", runtime.GOOS)
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
index a2f0926599..3a64c30e2b 100644
--- a/src/runtime/crash_test.go
+++ b/src/runtime/crash_test.go
@@ -184,7 +184,7 @@ func TestCrashHandler(t *testing.T) {
func testDeadlock(t *testing.T, name string) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
output := runTestProg(t, "testprog", name)
want := "fatal error: all goroutines are asleep - deadlock!\n"
@@ -211,7 +211,7 @@ func TestLockedDeadlock2(t *testing.T) {
func TestGoexitDeadlock(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
output := runTestProg(t, "testprog", "GoexitDeadlock")
want := "no goroutines (main called runtime.Goexit) - deadlock!"
@@ -311,7 +311,7 @@ panic: third panic
func TestGoexitCrash(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
output := runTestProg(t, "testprog", "GoexitExit")
want := "no goroutines (main called runtime.Goexit) - deadlock!"
@@ -372,7 +372,7 @@ func TestBreakpoint(t *testing.T) {
func TestGoexitInPanic(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
// see issue 8774: this code used to trigger an infinite recursion
output := runTestProg(t, "testprog", "GoexitInPanic")
@@ -439,7 +439,7 @@ func TestPanicAfterGoexit(t *testing.T) {
func TestRecoveredPanicAfterGoexit(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
output := runTestProg(t, "testprog", "RecoveredPanicAfterGoexit")
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
@@ -450,7 +450,7 @@ func TestRecoveredPanicAfterGoexit(t *testing.T) {
func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
t.Parallel()
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit")
@@ -462,7 +462,7 @@ func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
func TestRecoverBeforePanicAfterGoexit2(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
t.Parallel()
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit2")
diff --git a/src/runtime/time_test.go b/src/runtime/time_test.go
index afd9af2af4..f08682055b 100644
--- a/src/runtime/time_test.go
+++ b/src/runtime/time_test.go
@@ -22,7 +22,7 @@ func TestFakeTime(t *testing.T) {
// Faketime is advanced in checkdead. External linking brings in cgo,
// causing checkdead not working.
- testenv.MustInternalLink(t)
+ testenv.MustInternalLink(t, false)
t.Parallel()