"testing"
)
-// TestMain allows this test binary to run as a -toolexec wrapper for the 'go'
-// command. If LINK_TEST_TOOLEXEC is set, TestMain runs the binary as if it were
-// cmd/link, and otherwise runs the requested tool as a subprocess.
+// TestMain allows this test binary to run as a -toolexec wrapper for
+// the 'go' command. If LINK_TEST_TOOLEXEC is set, TestMain runs the
+// binary as if it were cmd/link, and otherwise runs the requested
+// tool as a subprocess.
//
// This allows the test to verify the behavior of the current contents of the
// cmd/link package even if the installed cmd/link binary is stale.
func TestMain(m *testing.M) {
- if os.Getenv("LINK_TEST_TOOLEXEC") == "" {
- // Not running as a -toolexec wrapper. Just run the tests.
- os.Exit(m.Run())
+ // Are we running as a toolexec wrapper? If so then run either
+ // the correct tool or this executable itself (for the linker).
+ // Running as toolexec wrapper.
+ if os.Getenv("LINK_TEST_TOOLEXEC") != "" {
+ if strings.TrimSuffix(filepath.Base(os.Args[1]), ".exe") == "link" {
+ // Running as a -toolexec linker, and the tool is cmd/link.
+ // Substitute this test binary for the linker.
+ os.Args = os.Args[1:]
+ main()
+ os.Exit(0)
+ }
+ // Running some other tool.
+ cmd := exec.Command(os.Args[1], os.Args[2:]...)
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ os.Exit(1)
+ }
+ os.Exit(0)
}
- if strings.TrimSuffix(filepath.Base(os.Args[1]), ".exe") == "link" {
- // Running as a -toolexec linker, and the tool is cmd/link.
- // Substitute this test binary for the linker.
- os.Args = os.Args[1:]
+ // Are we being asked to run as the linker (without toolexec)?
+ // If so then kick off main.
+ if os.Getenv("LINK_TEST_EXEC_LINKER") != "" {
main()
os.Exit(0)
}
- cmd := exec.Command(os.Args[1], os.Args[2:]...)
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- if err := cmd.Run(); err != nil {
- os.Exit(1)
+ if testExe, err := os.Executable(); err == nil {
+ // on wasm, some phones, we expect an error from os.Executable()
+ testLinker = testExe
}
- os.Exit(0)
+
+ // Not running as a -toolexec wrapper or as a linker executable.
+ // Just run the tests.
+ os.Exit(m.Run())
}
+// Path of the test executable being run.
+var testLinker string
+
func testDWARF(t *testing.T, buildmode string, expectDWARF bool, env ...string) {
testenv.MustHaveCGO(t)
testenv.MustHaveGoBuild(t)
--- /dev/null
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "cmd/internal/script/scripttest"
+ "internal/testenv"
+ "runtime"
+ "testing"
+)
+
+func TestScript(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ doReplacement := true
+ switch runtime.GOOS {
+ case "wasip1", "js":
+ // wasm doesn't support os.Executable, so we'll skip replacing
+ // the installed linker with our test binary.
+ doReplacement = false
+ }
+ repls := []scripttest.ToolReplacement{}
+ if doReplacement {
+ if testLinker == "" {
+ t.Fatalf("testLinker not set, can't replace")
+ }
+ repls = []scripttest.ToolReplacement{
+ scripttest.ToolReplacement{
+ ToolName: "link",
+ ReplacementPath: testLinker,
+ EnvVar: "LINK_TEST_EXEC_LINKER=1",
+ },
+ }
+ }
+ scripttest.RunToolScriptTest(t, repls, "testdata/script/*.txt")
+}
--- /dev/null
+
+# Test that the -randlayout flag randomizes function order and
+# generates a working binary.
+
+[short] skip
+
+# Build with random layout using one seed, then run ...
+go build -o prog123.exe -ldflags=-randlayout=123
+exec ./prog123.exe
+
+# ... now build with a different seed and run.
+go build -x -o prog456.exe -ldflags=-randlayout=456
+exec ./prog456.exe
+
+# Capture symbols (sorted by address)
+go tool nm prog123.exe
+cp stdout syms123.txt
+
+# Capture symbols (sorted by address)
+go tool nm prog456.exe
+cp stdout syms456.txt
+
+# Output should be different.
+! cmp syms123.txt syms456.txt
+
+-- go.mod --
+module main
+
+go 1.20
+
+-- mymain.go --
+package main
+
+func main() {
+ println("Hi mom!")
+}
+
+