1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
23 var AuthorPaidByTheColumnInch struct {
24 fog int `text:"London. Michaelmas term lately over, and the Lord Chancellor sitting in Lincoln’s Inn Hall. Implacable November weather. As much mud in the streets as if the waters had but newly retired from the face of the earth, and it would not be wonderful to meet a Megalosaurus, forty feet long or so, waddling like an elephantine lizard up Holborn Hill. Smoke lowering down from chimney-pots, making a soft black drizzle, with flakes of soot in it as big as full-grown snowflakes—gone into mourning, one might imagine, for the death of the sun. Dogs, undistinguishable in mire. Horses, scarcely better; splashed to their very blinkers. Foot passengers, jostling one another’s umbrellas in a general infection of ill temper, and losing their foot-hold at street-corners, where tens of thousands of other foot passengers have been slipping and sliding since the day broke (if this day ever broke), adding new deposits to the crust upon crust of mud, sticking at those points tenaciously to the pavement, and accumulating at compound interest. Fog everywhere. Fog up the river, where it flows among green aits and meadows; fog down the river, where it rolls defiled among the tiers of shipping and the waterside pollutions of a great (and dirty) city. Fog on the Essex marshes, fog on the Kentish heights. Fog creeping into the cabooses of collier-brigs; fog lying out on the yards and hovering in the rigging of great ships; fog drooping on the gunwales of barges and small boats. Fog in the eyes and throats of ancient Greenwich pensioners, wheezing by the firesides of their wards; fog in the stem and bowl of the afternoon pipe of the wrathful skipper, down in his close cabin; fog cruelly pinching the toes and fingers of his shivering little ‘prentice boy on deck. Chance people on the bridges peeping over the parapets into a nether sky of fog, with fog all round them, as if they were up in a balloon and hanging in the misty clouds. Gas looming through the fog in divers places in the streets, much as the sun may, from the spongey fields, be seen to loom by husbandman and ploughboy. Most of the shops lighted two hours before their time—as the gas seems to know, for it has a haggard and unwilling look. The raw afternoon is rawest, and the dense fog is densest, and the muddy streets are muddiest near that leaden-headed old obstruction, appropriate ornament for the threshold of a leaden-headed old corporation, Temple Bar. And hard by Temple Bar, in Lincoln’s Inn Hall, at the very heart of the fog, sits the Lord High Chancellor in his High Court of Chancery."`
26 wind int `text:"It was grand to see how the wind awoke, and bent the trees, and drove the rain before it like a cloud of smoke; and to hear the solemn thunder, and to see the lightning; and while thinking with awe of the tremendous powers by which our little lives are encompassed, to consider how beneficent they are, and how upon the smallest flower and leaf there was already a freshness poured from all this seeming rage, which seemed to make creation new again."`
28 jarndyce int `text:"Jarndyce and Jarndyce drones on. This scarecrow of a suit has, over the course of time, become so complicated, that no man alive knows what it means. The parties to it understand it least; but it has been observed that no two Chancery lawyers can talk about it for five minutes, without coming to a total disagreement as to all the premises. Innumerable children have been born into the cause; innumerable young people have married into it; innumerable old people have died out of it. Scores of persons have deliriously found themselves made parties in Jarndyce and Jarndyce, without knowing how or why; whole families have inherited legendary hatreds with the suit. The little plaintiff or defendant, who was promised a new rocking-horse when Jarndyce and Jarndyce should be settled, has grown up, possessed himself of a real horse, and trotted away into the other world. Fair wards of court have faded into mothers and grandmothers; a long procession of Chancellors has come in and gone out; the legion of bills in the suit have been transformed into mere bills of mortality; there are not three Jarndyces left upon the earth perhaps, since old Tom Jarndyce in despair blew his brains out at a coffee-house in Chancery Lane; but Jarndyce and Jarndyce still drags its dreary length before the Court, perennially hopeless."`
30 principle int `text:"The one great principle of the English law is, to make business for itself. There is no other principle distinctly, certainly, and consistently maintained through all its narrow turnings. Viewed by this light it becomes a coherent scheme, and not the monstrous maze the laity are apt to think it. Let them but once clearly perceive that its grand principle is to make business for itself at their expense, and surely they will cease to grumble."`
33 func TestLargeSymName(t *testing.T) {
34 // The compiler generates a symbol name using the string form of the
35 // type. This tests that the linker can read symbol names larger than
36 // the bufio buffer. Issue #15104.
37 _ = AuthorPaidByTheColumnInch
40 func TestIssue21703(t *testing.T) {
43 testenv.MustHaveGoBuild(t)
53 importcfgfile := filepath.Join(tmpdir, "importcfg")
54 testenv.WriteImportcfg(t, importcfgfile, nil)
56 err := os.WriteFile(filepath.Join(tmpdir, "main.go"), []byte(source), 0666)
58 t.Fatalf("failed to write main.go: %v\n", err)
61 cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgfile, "-p=main", "main.go")
63 out, err := cmd.CombinedOutput()
65 t.Fatalf("failed to compile main.go: %v, output: %s\n", err, out)
68 cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgfile, "main.o")
70 out, err = cmd.CombinedOutput()
72 t.Fatalf("failed to link main.o: %v, output: %s\n", err, out)
76 // TestIssue28429 ensures that the linker does not attempt to link
77 // sections not named *.o. Such sections may be used by a build system
78 // to, for example, save facts produced by a modular static analysis
79 // such as golang.org/x/tools/go/analysis.
80 func TestIssue28429(t *testing.T) {
83 testenv.MustHaveGoBuild(t)
87 write := func(name, content string) {
88 err := os.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
94 runGo := func(args ...string) {
95 cmd := exec.Command(testenv.GoToolPath(t), args...)
97 out, err := cmd.CombinedOutput()
99 t.Fatalf("'go %s' failed: %v, output: %s",
100 strings.Join(args, " "), err, out)
104 importcfgfile := filepath.Join(tmpdir, "importcfg")
105 testenv.WriteImportcfg(t, importcfgfile, nil)
107 // Compile a main package.
108 write("main.go", "package main; func main() {}")
109 runGo("tool", "compile", "-importcfg="+importcfgfile, "-p=main", "main.go")
110 runGo("tool", "pack", "c", "main.a", "main.o")
112 // Add an extra section with a short, non-.o name.
113 // This simulates an alternative build system.
114 write(".facts", "this is not an object file")
115 runGo("tool", "pack", "r", "main.a", ".facts")
117 // Verify that the linker does not attempt
118 // to compile the extra section.
119 runGo("tool", "link", "-importcfg="+importcfgfile, "main.a")
122 func TestUnresolved(t *testing.T) {
123 testenv.MustHaveGoBuild(t)
127 tmpdir := t.TempDir()
129 write := func(name, content string) {
130 err := os.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
136 // Test various undefined references. Because of issue #29852,
137 // this used to give confusing error messages because the
138 // linker would find an undefined reference to "zero" created
139 // by the runtime package.
141 write("go.mod", "module testunresolved\n")
142 write("main.go", `package main
157 cmd := exec.Command(testenv.GoToolPath(t), "build")
159 cmd.Env = append(os.Environ(),
160 "GOARCH=amd64", "GOOS=linux", "GOPATH="+filepath.Join(tmpdir, "_gopath"))
161 out, err := cmd.CombinedOutput()
163 t.Fatalf("expected build to fail, but it succeeded")
165 out = regexp.MustCompile("(?m)^#.*\n").ReplaceAll(out, nil)
167 want := `main.x: relocation target zero not defined
168 main.x: relocation target zero not defined
169 main.x: relocation target main.zero not defined
172 t.Fatalf("want:\n%sgot:\n%s", want, got)
176 func TestIssue33979(t *testing.T) {
177 testenv.MustHaveGoBuild(t)
178 testenv.MustHaveCGO(t)
179 testenv.MustInternalLink(t)
181 // Skip test on platforms that do not support cgo internal linking.
182 switch runtime.GOARCH {
184 t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
185 case "mips", "mipsle", "mips64", "mips64le":
186 t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
188 if runtime.GOOS == "aix" ||
189 runtime.GOOS == "windows" && runtime.GOARCH == "arm64" {
190 t.Skipf("Skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
195 tmpdir := t.TempDir()
197 write := func(name, content string) {
198 err := os.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
204 run := func(name string, args ...string) string {
205 cmd := exec.Command(name, args...)
207 out, err := cmd.CombinedOutput()
209 t.Fatalf("'go %s' failed: %v, output: %s", strings.Join(args, " "), err, out)
213 runGo := func(args ...string) string {
214 return run(testenv.GoToolPath(t), args...)
217 // Test object with undefined reference that was not generated
218 // by Go, resulting in an SXREF symbol being loaded during linking.
219 // Because of issue #33979, the SXREF symbol would be found during
220 // error reporting, resulting in confusing error messages.
222 write("main.go", `package main
228 // The following assembly must work on all architectures.
242 cc := strings.TrimSpace(runGo("env", "CC"))
243 cflags := strings.Fields(runGo("env", "GOGCCFLAGS"))
245 importcfgfile := filepath.Join(tmpdir, "importcfg")
246 testenv.WriteImportcfg(t, importcfgfile, nil)
248 // Compile, assemble and pack the Go and C code.
249 runGo("tool", "asm", "-p=main", "-gensymabis", "-o", "symabis", "x.s")
250 runGo("tool", "compile", "-importcfg="+importcfgfile, "-symabis", "symabis", "-p=main", "-o", "x1.o", "main.go")
251 runGo("tool", "asm", "-p=main", "-o", "x2.o", "x.s")
252 run(cc, append(cflags, "-c", "-o", "x3.o", "x.c")...)
253 runGo("tool", "pack", "c", "x.a", "x1.o", "x2.o", "x3.o")
255 // Now attempt to link using the internal linker.
256 cmd := exec.Command(testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgfile, "-linkmode=internal", "x.a")
258 out, err := cmd.CombinedOutput()
260 t.Fatalf("expected link to fail, but it succeeded")
262 re := regexp.MustCompile(`(?m)^main\(.*text\): relocation target undefined not defined$`)
264 t.Fatalf("got:\n%q\nwant:\n%s", out, re)
268 func TestBuildForTvOS(t *testing.T) {
269 testenv.MustHaveCGO(t)
270 testenv.MustHaveGoBuild(t)
272 // Only run this on darwin/amd64, where we can cross build for tvOS.
273 if runtime.GOARCH != "amd64" || runtime.GOOS != "darwin" {
274 t.Skip("skipping on non-darwin/amd64 platform")
276 if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" {
277 t.Skip("skipping in -short mode with $GO_BUILDER_NAME empty")
279 if err := exec.Command("xcrun", "--help").Run(); err != nil {
280 t.Skipf("error running xcrun, required for iOS cross build: %v", err)
285 sdkPath, err := exec.Command("xcrun", "--sdk", "appletvos", "--show-sdk-path").Output()
287 t.Skip("failed to locate appletvos SDK, skipping")
293 "-isysroot", strings.TrimSpace(string(sdkPath)),
294 "-mtvos-version-min=12.0",
297 CGO_LDFLAGS := []string{"-framework", "CoreFoundation"}
298 lib := filepath.Join("testdata", "testBuildFortvOS", "lib.go")
299 tmpDir := t.TempDir()
301 ar := filepath.Join(tmpDir, "lib.a")
302 cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", ar, lib)
303 cmd.Env = append(os.Environ(),
307 "CC="+strings.Join(CC, " "),
308 "CGO_CFLAGS=", // ensure CGO_CFLAGS does not contain any flags. Issue #35459
309 "CGO_LDFLAGS="+strings.Join(CGO_LDFLAGS, " "),
311 if out, err := cmd.CombinedOutput(); err != nil {
312 t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
315 link := exec.Command(CC[0], CC[1:]...)
316 link.Args = append(link.Args, CGO_LDFLAGS...)
317 link.Args = append(link.Args, "-o", filepath.Join(tmpDir, "a.out")) // Avoid writing to package directory.
318 link.Args = append(link.Args, ar, filepath.Join("testdata", "testBuildFortvOS", "main.m"))
319 if out, err := link.CombinedOutput(); err != nil {
320 t.Fatalf("%v: %v:\n%s", link.Args, err, out)
327 var Z = [99999]int{99998:12345} // make it large enough to be mmaped
328 func main() { println(X) }
331 func TestXFlag(t *testing.T) {
332 testenv.MustHaveGoBuild(t)
336 tmpdir := t.TempDir()
338 src := filepath.Join(tmpdir, "main.go")
339 err := os.WriteFile(src, []byte(testXFlagSrc), 0666)
344 cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-X=main.X=meow", "-o", filepath.Join(tmpdir, "main"), src)
345 if out, err := cmd.CombinedOutput(); err != nil {
346 t.Errorf("%v: %v:\n%s", cmd.Args, err, out)
350 var testMachOBuildVersionSrc = `
355 func TestMachOBuildVersion(t *testing.T) {
356 testenv.MustHaveGoBuild(t)
360 tmpdir := t.TempDir()
362 src := filepath.Join(tmpdir, "main.go")
363 err := os.WriteFile(src, []byte(testMachOBuildVersionSrc), 0666)
368 exe := filepath.Join(tmpdir, "main")
369 cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal", "-o", exe, src)
370 cmd.Env = append(os.Environ(),
375 if out, err := cmd.CombinedOutput(); err != nil {
376 t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
378 exef, err := os.Open(exe)
383 exem, err := macho.NewFile(exef)
388 const LC_BUILD_VERSION = 0x32
389 checkMin := func(ver uint32) {
390 major, minor := (ver>>16)&0xff, (ver>>8)&0xff
391 if major != 10 || minor < 9 {
392 t.Errorf("LC_BUILD_VERSION version %d.%d < 10.9", major, minor)
395 for _, cmd := range exem.Loads {
397 type_ := exem.ByteOrder.Uint32(raw)
398 if type_ != LC_BUILD_VERSION {
401 osVer := exem.ByteOrder.Uint32(raw[12:])
403 sdkVer := exem.ByteOrder.Uint32(raw[16:])
409 t.Errorf("no LC_BUILD_VERSION load command found")
413 const Issue34788src = `
417 func Blah(i int) int {
418 a := [...]int{1, 2, 3, 4, 5, 6, 7, 8}
423 func TestIssue34788Android386TLSSequence(t *testing.T) {
424 testenv.MustHaveGoBuild(t)
426 // This is a cross-compilation test, so it doesn't make
427 // sense to run it on every GOOS/GOARCH combination. Limit
428 // the test to amd64 + darwin/linux.
429 if runtime.GOARCH != "amd64" ||
430 (runtime.GOOS != "darwin" && runtime.GOOS != "linux") {
431 t.Skip("skipping on non-{linux,darwin}/amd64 platform")
436 tmpdir := t.TempDir()
438 src := filepath.Join(tmpdir, "blah.go")
439 err := os.WriteFile(src, []byte(Issue34788src), 0666)
444 obj := filepath.Join(tmpdir, "blah.o")
445 cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=blah", "-o", obj, src)
446 cmd.Env = append(os.Environ(), "GOARCH=386", "GOOS=android")
447 if out, err := cmd.CombinedOutput(); err != nil {
448 t.Fatalf("failed to compile blah.go: %v, output: %s\n", err, out)
451 // Run objdump on the resulting object.
452 cmd = exec.Command(testenv.GoToolPath(t), "tool", "objdump", obj)
453 out, oerr := cmd.CombinedOutput()
455 t.Fatalf("failed to objdump blah.o: %v, output: %s\n", oerr, out)
458 // Sift through the output; we should not be seeing any R_TLS_LE relocs.
459 scanner := bufio.NewScanner(bytes.NewReader(out))
461 line := scanner.Text()
462 if strings.Contains(line, "R_TLS_LE") {
463 t.Errorf("objdump output contains unexpected R_TLS_LE reloc: %s", line)
468 const testStrictDupGoSrc = `
474 const testStrictDupAsmSrc1 = `
475 #include "textflag.h"
476 TEXT ·f(SB), NOSPLIT|DUPOK, $0-0
480 const testStrictDupAsmSrc2 = `
481 #include "textflag.h"
482 TEXT ·f(SB), NOSPLIT|DUPOK, $0-0
486 const testStrictDupAsmSrc3 = `
487 #include "textflag.h"
488 GLOBL ·rcon(SB), RODATA|DUPOK, $64
491 const testStrictDupAsmSrc4 = `
492 #include "textflag.h"
493 GLOBL ·rcon(SB), RODATA|DUPOK, $32
496 func TestStrictDup(t *testing.T) {
497 // Check that -strictdups flag works.
498 testenv.MustHaveGoBuild(t)
500 asmfiles := []struct {
504 {"a", testStrictDupAsmSrc1},
505 {"b", testStrictDupAsmSrc2},
506 {"c", testStrictDupAsmSrc3},
507 {"d", testStrictDupAsmSrc4},
512 tmpdir := t.TempDir()
514 src := filepath.Join(tmpdir, "x.go")
515 err := os.WriteFile(src, []byte(testStrictDupGoSrc), 0666)
519 for _, af := range asmfiles {
520 src = filepath.Join(tmpdir, af.fname+".s")
521 err = os.WriteFile(src, []byte(af.payload), 0666)
526 src = filepath.Join(tmpdir, "go.mod")
527 err = os.WriteFile(src, []byte("module teststrictdup\n"), 0666)
532 cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-strictdups=1")
534 out, err := cmd.CombinedOutput()
536 t.Errorf("linking with -strictdups=1 failed: %v\n%s", err, string(out))
538 if !bytes.Contains(out, []byte("mismatched payload")) {
539 t.Errorf("unexpected output:\n%s", out)
542 cmd = exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-strictdups=2")
544 out, err = cmd.CombinedOutput()
546 t.Errorf("linking with -strictdups=2 did not fail")
548 // NB: on amd64 we get the 'new length' error, on arm64 the 'different
550 if !(bytes.Contains(out, []byte("mismatched payload: new length")) ||
551 bytes.Contains(out, []byte("mismatched payload: same length but different contents"))) ||
552 !bytes.Contains(out, []byte("mismatched payload: different sizes")) {
553 t.Errorf("unexpected output:\n%s", out)
557 const testFuncAlignSrc = `
563 var alignPcFnAddr uintptr
566 if alignPcFnAddr % 512 != 0 {
567 fmt.Printf("expected 512 bytes alignment, got %v\n", alignPcFnAddr)
574 const testFuncAlignAsmSrc = `
575 #include "textflag.h"
577 TEXT ·alignPc(SB),NOSPLIT, $0-0
583 GLOBL ·alignPcFnAddr(SB),RODATA,$8
584 DATA ·alignPcFnAddr(SB)/8,$·alignPc(SB)
587 // TestFuncAlign verifies that the address of a function can be aligned
588 // with a specific value on arm64.
589 func TestFuncAlign(t *testing.T) {
590 if runtime.GOARCH != "arm64" || runtime.GOOS != "linux" {
591 t.Skip("skipping on non-linux/arm64 platform")
593 testenv.MustHaveGoBuild(t)
597 tmpdir := t.TempDir()
599 src := filepath.Join(tmpdir, "go.mod")
600 err := os.WriteFile(src, []byte("module cmd/link/TestFuncAlign/falign"), 0666)
604 src = filepath.Join(tmpdir, "falign.go")
605 err = os.WriteFile(src, []byte(testFuncAlignSrc), 0666)
609 src = filepath.Join(tmpdir, "falign.s")
610 err = os.WriteFile(src, []byte(testFuncAlignAsmSrc), 0666)
615 // Build and run with old object file format.
616 cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "falign")
618 out, err := cmd.CombinedOutput()
620 t.Errorf("build failed: %v", err)
622 cmd = exec.Command(tmpdir + "/falign")
623 out, err = cmd.CombinedOutput()
625 t.Errorf("failed to run with err %v, output: %s", err, out)
627 if string(out) != "PASS" {
628 t.Errorf("unexpected output: %s\n", out)
632 const testTrampSrc = `
639 if e := recover(); e == nil {
640 panic("did not panic")
646 // Test deferreturn trampolines. See issue #39049.
647 func f1() { defer f2() }
648 func f2() { panic("XXX") }
651 func TestTrampoline(t *testing.T) {
652 // Test that trampoline insertion works as expected.
653 // For stress test, we set -debugtramp=2 flag, which sets a very low
654 // threshold for trampoline generation, and essentially all cross-package
655 // calls will use trampolines.
656 buildmodes := []string{"default"}
657 switch runtime.GOARCH {
658 case "arm", "arm64", "ppc64":
660 // Trampolines are generated differently when internal linking PIE, test them too.
661 buildmodes = append(buildmodes, "pie")
663 t.Skipf("trampoline insertion is not implemented on %s", runtime.GOARCH)
666 testenv.MustHaveGoBuild(t)
670 tmpdir := t.TempDir()
672 src := filepath.Join(tmpdir, "hello.go")
673 err := os.WriteFile(src, []byte(testTrampSrc), 0666)
677 exe := filepath.Join(tmpdir, "hello.exe")
679 for _, mode := range buildmodes {
680 cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2", "-o", exe, src)
681 out, err := cmd.CombinedOutput()
683 t.Fatalf("build (%s) failed: %v\n%s", mode, err, out)
685 cmd = exec.Command(exe)
686 out, err = cmd.CombinedOutput()
688 t.Errorf("executable failed to run (%s): %v\n%s", mode, err, out)
690 if string(out) != "hello\n" {
691 t.Errorf("unexpected output (%s):\n%s", mode, out)
696 const testTrampCgoSrc = `
699 // #include <stdio.h>
700 // void CHello() { printf("hello\n"); fflush(stdout); }
708 func TestTrampolineCgo(t *testing.T) {
709 // Test that trampoline insertion works for cgo code.
710 // For stress test, we set -debugtramp=2 flag, which sets a very low
711 // threshold for trampoline generation, and essentially all cross-package
712 // calls will use trampolines.
713 buildmodes := []string{"default"}
714 switch runtime.GOARCH {
715 case "arm", "arm64", "ppc64":
717 // Trampolines are generated differently when internal linking PIE, test them too.
718 buildmodes = append(buildmodes, "pie")
720 t.Skipf("trampoline insertion is not implemented on %s", runtime.GOARCH)
723 testenv.MustHaveGoBuild(t)
724 testenv.MustHaveCGO(t)
728 tmpdir := t.TempDir()
730 src := filepath.Join(tmpdir, "hello.go")
731 err := os.WriteFile(src, []byte(testTrampCgoSrc), 0666)
735 exe := filepath.Join(tmpdir, "hello.exe")
737 for _, mode := range buildmodes {
738 cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2", "-o", exe, src)
739 out, err := cmd.CombinedOutput()
741 t.Fatalf("build (%s) failed: %v\n%s", mode, err, out)
743 cmd = exec.Command(exe)
744 out, err = cmd.CombinedOutput()
746 t.Errorf("executable failed to run (%s): %v\n%s", mode, err, out)
748 if string(out) != "hello\n" && string(out) != "hello\r\n" {
749 t.Errorf("unexpected output (%s):\n%s", mode, out)
752 // Test internal linking mode.
754 if runtime.GOARCH == "ppc64" || (runtime.GOARCH == "arm64" && runtime.GOOS == "windows") || !testenv.CanInternalLink() {
755 return // internal linking cgo is not supported
757 cmd = exec.Command(testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2 -linkmode=internal", "-o", exe, src)
758 out, err = cmd.CombinedOutput()
760 t.Fatalf("build (%s) failed: %v\n%s", mode, err, out)
762 cmd = exec.Command(exe)
763 out, err = cmd.CombinedOutput()
765 t.Errorf("executable failed to run (%s): %v\n%s", mode, err, out)
767 if string(out) != "hello\n" && string(out) != "hello\r\n" {
768 t.Errorf("unexpected output (%s):\n%s", mode, out)
773 func TestIndexMismatch(t *testing.T) {
774 // Test that index mismatch will cause a link-time error (not run-time error).
775 // This shouldn't happen with "go build". We invoke the compiler and the linker
776 // manually, and try to "trick" the linker with an inconsistent object file.
777 testenv.MustHaveGoBuild(t)
781 tmpdir := t.TempDir()
783 aSrc := filepath.Join("testdata", "testIndexMismatch", "a.go")
784 bSrc := filepath.Join("testdata", "testIndexMismatch", "b.go")
785 mSrc := filepath.Join("testdata", "testIndexMismatch", "main.go")
786 aObj := filepath.Join(tmpdir, "a.o")
787 mObj := filepath.Join(tmpdir, "main.o")
788 exe := filepath.Join(tmpdir, "main.exe")
790 importcfgFile := filepath.Join(tmpdir, "stdlib.importcfg")
791 testenv.WriteImportcfg(t, importcfgFile, nil)
792 importcfgWithAFile := filepath.Join(tmpdir, "witha.importcfg")
793 testenv.WriteImportcfg(t, importcfgWithAFile, map[string]string{"a": aObj})
795 // Build a program with main package importing package a.
796 cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgFile, "-p=a", "-o", aObj, aSrc)
798 out, err := cmd.CombinedOutput()
800 t.Fatalf("compiling a.go failed: %v\n%s", err, out)
802 cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgWithAFile, "-p=main", "-I", tmpdir, "-o", mObj, mSrc)
804 out, err = cmd.CombinedOutput()
806 t.Fatalf("compiling main.go failed: %v\n%s", err, out)
808 cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgWithAFile, "-L", tmpdir, "-o", exe, mObj)
810 out, err = cmd.CombinedOutput()
812 t.Errorf("linking failed: %v\n%s", err, out)
815 // Now, overwrite a.o with the object of b.go. This should
816 // result in an index mismatch.
817 cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgFile, "-p=a", "-o", aObj, bSrc)
819 out, err = cmd.CombinedOutput()
821 t.Fatalf("compiling a.go failed: %v\n%s", err, out)
823 cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgWithAFile, "-L", tmpdir, "-o", exe, mObj)
825 out, err = cmd.CombinedOutput()
827 t.Fatalf("linking didn't fail")
829 if !bytes.Contains(out, []byte("fingerprint mismatch")) {
830 t.Errorf("did not see expected error message. out:\n%s", out)
834 func TestPErsrcBinutils(t *testing.T) {
835 // Test that PE rsrc section is handled correctly (issue 39658).
836 testenv.MustHaveGoBuild(t)
838 if (runtime.GOARCH != "386" && runtime.GOARCH != "amd64") || runtime.GOOS != "windows" {
839 // This test is limited to amd64 and 386, because binutils is limited as such
840 t.Skipf("this is only for windows/amd64 and windows/386")
845 tmpdir := t.TempDir()
847 pkgdir := filepath.Join("testdata", "pe-binutils")
848 exe := filepath.Join(tmpdir, "a.exe")
849 cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
851 // cmd.Env = append(os.Environ(), "GOOS=windows", "GOARCH=amd64") // uncomment if debugging in a cross-compiling environment
852 out, err := cmd.CombinedOutput()
854 t.Fatalf("building failed: %v, output:\n%s", err, out)
857 // Check that the binary contains the rsrc data
858 b, err := os.ReadFile(exe)
860 t.Fatalf("reading output failed: %v", err)
862 if !bytes.Contains(b, []byte("Hello Gophers!")) {
863 t.Fatalf("binary does not contain expected content")
867 func TestPErsrcLLVM(t *testing.T) {
868 // Test that PE rsrc section is handled correctly (issue 39658).
869 testenv.MustHaveGoBuild(t)
871 if runtime.GOOS != "windows" {
872 t.Skipf("this is a windows-only test")
877 tmpdir := t.TempDir()
879 pkgdir := filepath.Join("testdata", "pe-llvm")
880 exe := filepath.Join(tmpdir, "a.exe")
881 cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
883 // cmd.Env = append(os.Environ(), "GOOS=windows", "GOARCH=amd64") // uncomment if debugging in a cross-compiling environment
884 out, err := cmd.CombinedOutput()
886 t.Fatalf("building failed: %v, output:\n%s", err, out)
889 // Check that the binary contains the rsrc data
890 b, err := os.ReadFile(exe)
892 t.Fatalf("reading output failed: %v", err)
894 if !bytes.Contains(b, []byte("resname RCDATA a.rc")) {
895 t.Fatalf("binary does not contain expected content")
899 func TestContentAddressableSymbols(t *testing.T) {
900 // Test that the linker handles content-addressable symbols correctly.
901 testenv.MustHaveGoBuild(t)
905 src := filepath.Join("testdata", "testHashedSyms", "p.go")
906 cmd := exec.Command(testenv.GoToolPath(t), "run", src)
907 out, err := cmd.CombinedOutput()
909 t.Errorf("command %s failed: %v\n%s", cmd, err, out)
913 func TestReadOnly(t *testing.T) {
914 // Test that read-only data is indeed read-only.
915 testenv.MustHaveGoBuild(t)
919 src := filepath.Join("testdata", "testRO", "x.go")
920 cmd := exec.Command(testenv.GoToolPath(t), "run", src)
921 out, err := cmd.CombinedOutput()
923 t.Errorf("running test program did not fail. output:\n%s", out)
927 const testIssue38554Src = `
934 return T{} // compiler will make a large stmp symbol, but not used.
943 func TestIssue38554(t *testing.T) {
944 testenv.MustHaveGoBuild(t)
948 tmpdir := t.TempDir()
950 src := filepath.Join(tmpdir, "x.go")
951 err := os.WriteFile(src, []byte(testIssue38554Src), 0666)
953 t.Fatalf("failed to write source file: %v", err)
955 exe := filepath.Join(tmpdir, "x.exe")
956 cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, src)
957 out, err := cmd.CombinedOutput()
959 t.Fatalf("build failed: %v\n%s", err, out)
962 fi, err := os.Stat(exe)
964 t.Fatalf("failed to stat output file: %v", err)
967 // The test program is not much different from a helloworld, which is
968 // typically a little over 1 MB. We allow 5 MB. If the bad stmp is live,
969 // it will be over 10 MB.
971 if got := fi.Size(); got > want {
972 t.Errorf("binary too big: got %d, want < %d", got, want)
976 const testIssue42396src = `
989 func TestIssue42396(t *testing.T) {
990 testenv.MustHaveGoBuild(t)
992 if !platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) {
993 t.Skip("no race detector support")
998 tmpdir := t.TempDir()
1000 src := filepath.Join(tmpdir, "main.go")
1001 err := os.WriteFile(src, []byte(testIssue42396src), 0666)
1003 t.Fatalf("failed to write source file: %v", err)
1005 exe := filepath.Join(tmpdir, "main.exe")
1006 cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=-race", "-o", exe, src)
1007 out, err := cmd.CombinedOutput()
1009 t.Fatalf("build unexpectedly succeeded")
1012 // Check to make sure that we see a reasonable error message
1014 if strings.Contains(string(out), "panic:") {
1015 t.Fatalf("build should not fail with panic:\n%s", out)
1017 const want = "reference to undefined builtin"
1018 if !strings.Contains(string(out), want) {
1019 t.Fatalf("error message incorrect: expected it to contain %q but instead got:\n%s\n", want, out)
1023 const testLargeRelocSrc = `
1026 var x = [1<<25]byte{1<<23: 23, 1<<24: 24}
1028 var addr = [...]*byte{
1038 // check relocations in instructions
1039 check(x[1<<23-1], 0)
1041 check(x[1<<23+1], 0)
1042 check(x[1<<24-1], 0)
1044 check(x[1<<24+1], 0)
1046 // check absolute address relocations in data
1055 func check(x, y byte) {
1062 func TestLargeReloc(t *testing.T) {
1063 // Test that large relocation addend is handled correctly.
1064 // In particular, on darwin/arm64 when external linking,
1065 // Mach-O relocation has only 24-bit addend. See issue #42738.
1066 testenv.MustHaveGoBuild(t)
1069 tmpdir := t.TempDir()
1071 src := filepath.Join(tmpdir, "x.go")
1072 err := os.WriteFile(src, []byte(testLargeRelocSrc), 0666)
1074 t.Fatalf("failed to write source file: %v", err)
1076 cmd := exec.Command(testenv.GoToolPath(t), "run", src)
1077 out, err := cmd.CombinedOutput()
1079 t.Errorf("build failed: %v. output:\n%s", err, out)
1082 if testenv.HasCGO() { // currently all targets that support cgo can external link
1083 cmd = exec.Command(testenv.GoToolPath(t), "run", "-ldflags=-linkmode=external", src)
1084 out, err = cmd.CombinedOutput()
1086 t.Fatalf("build failed: %v. output:\n%s", err, out)
1091 func TestUnlinkableObj(t *testing.T) {
1092 // Test that the linker emits an error with unlinkable object.
1093 testenv.MustHaveGoBuild(t)
1096 if buildcfg.Experiment.Unified {
1097 t.Skip("TODO(mdempsky): Fix ICE when importing unlinkable objects for GOEXPERIMENT=unified")
1100 tmpdir := t.TempDir()
1102 xSrc := filepath.Join(tmpdir, "x.go")
1103 pSrc := filepath.Join(tmpdir, "p.go")
1104 xObj := filepath.Join(tmpdir, "x.o")
1105 pObj := filepath.Join(tmpdir, "p.o")
1106 exe := filepath.Join(tmpdir, "x.exe")
1107 err := os.WriteFile(xSrc, []byte("package main\nimport _ \"p\"\nfunc main() {}\n"), 0666)
1109 t.Fatalf("failed to write source file: %v", err)
1111 err = os.WriteFile(pSrc, []byte("package p\n"), 0666)
1113 t.Fatalf("failed to write source file: %v", err)
1115 cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", pObj, pSrc) // without -p
1116 out, err := cmd.CombinedOutput()
1118 t.Fatalf("compile p.go failed: %v. output:\n%s", err, out)
1120 cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-I", tmpdir, "-p=main", "-o", xObj, xSrc)
1121 out, err = cmd.CombinedOutput()
1123 t.Fatalf("compile x.go failed: %v. output:\n%s", err, out)
1125 cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "-L", tmpdir, "-o", exe, xObj)
1126 out, err = cmd.CombinedOutput()
1128 t.Fatalf("link did not fail")
1130 if !bytes.Contains(out, []byte("unlinkable object")) {
1131 t.Errorf("did not see expected error message. out:\n%s", out)
1134 // It is okay to omit -p for (only) main package.
1135 cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=p", "-o", pObj, pSrc)
1136 out, err = cmd.CombinedOutput()
1138 t.Fatalf("compile p.go failed: %v. output:\n%s", err, out)
1140 cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-I", tmpdir, "-o", xObj, xSrc) // without -p
1141 out, err = cmd.CombinedOutput()
1143 t.Fatalf("compile failed: %v. output:\n%s", err, out)
1145 cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "-L", tmpdir, "-o", exe, xObj)
1146 out, err = cmd.CombinedOutput()
1148 t.Errorf("link failed: %v. output:\n%s", err, out)