aboutsummaryrefslogtreecommitdiff
path: root/go
diff options
context:
space:
mode:
authorRahul Chaudhry <rahulchaudhry@chromium.org>2016-03-30 10:20:14 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-03-31 16:29:49 +0000
commit878f9d1108230185d5eb9962a11bfaccf534b1f9 (patch)
tree56604b957d4e330474c5b63e795fc02a96252dfc /go
parent72725f0149c91eda72e6734717f5c857f4659d65 (diff)
downloadtoolchain-utils-878f9d1108230185d5eb9962a11bfaccf534b1f9.tar.gz
toolchain-utils: scripts and patches for running the full Go testsuite.
BUG=None TEST=None Change-Id: I37a4cd0c98c3aefe940472990ed3fec5691e6df7 Reviewed-on: https://chrome-internal-review.googlesource.com/253047 Commit-Ready: Rahul Chaudhry <rahulchaudhry@google.com> Tested-by: Rahul Chaudhry <rahulchaudhry@google.com> Reviewed-by: Luis Lozano <llozano@chromium.org>
Diffstat (limited to 'go')
-rwxr-xr-xgo/go_local8
-rw-r--r--go/patch/go0.patch33
-rw-r--r--go/patch/go1.patch50
-rw-r--r--go/patch/go2.patch173
-rw-r--r--go/patch/go3.patch711
-rw-r--r--go/patch/go4.patch101
-rw-r--r--go/patch/go5.patch198
-rw-r--r--go/patch/go6.patch65
-rw-r--r--go/patch/go7.patch139
-rwxr-xr-xgo/test_go88
10 files changed, 1566 insertions, 0 deletions
diff --git a/go/go_local b/go/go_local
new file mode 100755
index 00000000..92954ef8
--- /dev/null
+++ b/go/go_local
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# Invoke the Go compiler for localhost.
+
+GOOS="linux" GOARCH="amd64" CGO_ENABLED="1" \
+ CC="gcc" \
+ CXX="g++" \
+ exec go "$@"
diff --git a/go/patch/go0.patch b/go/patch/go0.patch
new file mode 100644
index 00000000..27e1451e
--- /dev/null
+++ b/go/patch/go0.patch
@@ -0,0 +1,33 @@
+testenv: look for "go" executable in path.
+
+--- src/go/build/deps_test.go
++++ src/go/build/deps_test.go
+@@ -168,7 +168,7 @@ var pkgDeps = map[string][]string{
+ "testing": {"L2", "flag", "fmt", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
+ "testing/iotest": {"L2", "log"},
+ "testing/quick": {"L2", "flag", "fmt", "reflect"},
+- "internal/testenv": {"L2", "os", "testing"},
++ "internal/testenv": {"L2", "os", "os/exec", "testing"},
+
+ // L4 is defined as L3+fmt+log+time, because in general once
+ // you're using L3 packages, use of fmt, log, or time is not a big deal.
+--- src/internal/testenv/testenv.go
++++ src/internal/testenv/testenv.go
+@@ -12,6 +12,7 @@ package testenv
+
+ import (
+ "os"
++ "os/exec"
+ "runtime"
+ "strings"
+ "testing"
+@@ -36,6 +37,9 @@ func HasGoBuild() bool {
+ return false
+ }
+ }
++ if _, err := exec.LookPath("go"); err != nil {
++ return false
++ }
+ return true
+ }
+
diff --git a/go/patch/go1.patch b/go/patch/go1.patch
new file mode 100644
index 00000000..49d229ec
--- /dev/null
+++ b/go/patch/go1.patch
@@ -0,0 +1,50 @@
+test: enable some tests on android/arm64.
+
+--- test/chanlinear.go
++++ test/chanlinear.go
+@@ -1,4 +1,4 @@
+-// +build darwin linux
++// +build darwin linux android
+ // run
+
+ // Copyright 2014 The Go Authors. All rights reserved.
+--- test/fixedbugs/bug385_64.go
++++ test/fixedbugs/bug385_64.go
+@@ -1,4 +1,4 @@
+-// +build amd64
++// +build amd64 arm64
+ // errorcheck
+
+ // Copyright 2011 The Go Authors. All rights reserved.
+--- test/fixedbugs/issue10607.go
++++ test/fixedbugs/issue10607.go
+@@ -1,4 +1,4 @@
+-// +build linux,!ppc64,!ppc64le,!mips64,!mips64le
++// +build linux,!ppc64,!ppc64le,!mips64,!mips64le android
+ // run
+
+ // Copyright 2015 The Go Authors. All rights reserved.
+--- test/fixedbugs/issue6036.go
++++ test/fixedbugs/issue6036.go
+@@ -1,4 +1,4 @@
+-// +build amd64
++// +build amd64 arm64
+ // compile
+
+ // Copyright 2013 The Go Authors. All rights reserved.
+--- test/maplinear.go
++++ test/maplinear.go
+@@ -1,4 +1,4 @@
+-// +build darwin linux
++// +build darwin linux android
+ // run
+
+ // Copyright 2013 The Go Authors. All rights reserved.
+--- test/recover4.go
++++ test/recover4.go
+@@ -1,4 +1,4 @@
+-// +build linux darwin
++// +build linux android darwin
+ // run
+
+ // Copyright 2015 The Go Authors. All rights reserved.
diff --git a/go/patch/go2.patch b/go/patch/go2.patch
new file mode 100644
index 00000000..dfc236a4
--- /dev/null
+++ b/go/patch/go2.patch
@@ -0,0 +1,173 @@
+test: add -target flag.
+
+--- test/run.go
++++ test/run.go
+@@ -37,9 +37,9 @@ var (
+ numParallel = flag.Int("n", runtime.NumCPU(), "number of parallel tests to run")
+ summary = flag.Bool("summary", false, "show summary of results")
+ showSkips = flag.Bool("show_skips", false, "show skipped tests")
+- linkshared = flag.Bool("linkshared", false, "")
+ updateErrors = flag.Bool("update_errors", false, "update error messages in test file based on compiler output")
+ runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run")
++ target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
+
+ shard = flag.Int("shard", 0, "shard index to run. Only applicable if -shards is non-zero.")
+ shards = flag.Int("shards", 0, "number of shards. If 0, all tests are run. This is used by the continuous build.")
+@@ -192,19 +192,11 @@ func goFiles(dir string) []string {
+ type runCmd func(...string) ([]byte, error)
+
+ func compileFile(runcmd runCmd, longname string) (out []byte, err error) {
+- cmd := []string{"go", "tool", "compile", "-e"}
+- if *linkshared {
+- cmd = append(cmd, "-dynlink", "-installsuffix=dynlink")
+- }
+- cmd = append(cmd, longname)
+- return runcmd(cmd...)
++ return runcmd(findGoCmd(), "tool", "compile", "-e", longname)
+ }
+
+ func compileInDir(runcmd runCmd, dir string, names ...string) (out []byte, err error) {
+- cmd := []string{"go", "tool", "compile", "-e", "-D", ".", "-I", "."}
+- if *linkshared {
+- cmd = append(cmd, "-dynlink", "-installsuffix=dynlink")
+- }
++ cmd := []string{findGoCmd(), "tool", "compile", "-e", "-D", ".", "-I", "."}
+ for _, name := range names {
+ cmd = append(cmd, filepath.Join(dir, name))
+ }
+@@ -213,15 +205,21 @@ func compileInDir(runcmd runCmd, dir string, names ...string) (out []byte, err e
+
+ func linkFile(runcmd runCmd, goname string) (err error) {
+ pfile := strings.Replace(goname, ".go", ".o", -1)
+- cmd := []string{"go", "tool", "link", "-w", "-o", "a.exe", "-L", "."}
+- if *linkshared {
+- cmd = append(cmd, "-linkshared", "-installsuffix=dynlink")
+- }
+- cmd = append(cmd, pfile)
+- _, err = runcmd(cmd...)
++ _, err = runcmd(findGoCmd(), "tool", "link", "-w", "-o", "a.exe", "-L", ".", pfile)
+ return
+ }
+
++func goRun(runcmd runCmd, goname string, args ...string) (out []byte, err error) {
++ cmd := []string{findGoCmd(), "run"}
++ if len(findExecCmd()) > 0 {
++ cmd = append(cmd, "-exec")
++ cmd = append(cmd, findExecCmd()...)
++ }
++ cmd = append(cmd, goname)
++ cmd = append(cmd, args...)
++ return runcmd(cmd...)
++}
++
+ // skipError describes why a test was skipped.
+ type skipError string
+
+@@ -530,8 +528,7 @@ func (t *test) run() {
+ t.err = fmt.Errorf("unimplemented action %q", action)
+
+ case "errorcheck":
+- cmdline := []string{"go", "tool", "compile", "-e", "-o", "a.o"}
+- // No need to add -dynlink even if linkshared if we're just checking for errors...
++ cmdline := []string{findGoCmd(), "tool", "compile", "-e", "-o", "a.o"}
+ cmdline = append(cmdline, flags...)
+ cmdline = append(cmdline, long)
+ out, err := runcmd(cmdline...)
+@@ -640,19 +637,14 @@ func (t *test) run() {
+ }
+
+ case "build":
+- _, err := runcmd("go", "build", "-o", "a.exe", long)
++ _, err := runcmd(findGoCmd(), "build", "-o", "a.exe", long)
+ if err != nil {
+ t.err = err
+ }
+
+ case "run":
+ useTmp = false
+- cmd := []string{"go", "run"}
+- if *linkshared {
+- cmd = append(cmd, "-linkshared")
+- }
+- cmd = append(cmd, t.goFileName())
+- out, err := runcmd(append(cmd, args...)...)
++ out, err := goRun(runcmd, t.goFileName(), args...)
+ if err != nil {
+ t.err = err
+ return
+@@ -667,12 +659,7 @@ func (t *test) run() {
+ <-rungatec
+ }()
+ useTmp = false
+- cmd := []string{"go", "run"}
+- if *linkshared {
+- cmd = append(cmd, "-linkshared")
+- }
+- cmd = append(cmd, t.goFileName())
+- out, err := runcmd(append(cmd, args...)...)
++ out, err := goRun(runcmd, t.goFileName(), args...)
+ if err != nil {
+ t.err = err
+ return
+@@ -682,12 +669,7 @@ func (t *test) run() {
+ t.err = fmt.Errorf("write tempfile:%s", err)
+ return
+ }
+- cmd = []string{"go", "run"}
+- if *linkshared {
+- cmd = append(cmd, "-linkshared")
+- }
+- cmd = append(cmd, tfile)
+- out, err = runcmd(cmd...)
++ out, err = goRun(runcmd, tfile)
+ if err != nil {
+ t.err = err
+ return
+@@ -698,12 +680,7 @@ func (t *test) run() {
+
+ case "errorcheckoutput":
+ useTmp = false
+- cmd := []string{"go", "run"}
+- if *linkshared {
+- cmd = append(cmd, "-linkshared")
+- }
+- cmd = append(cmd, t.goFileName())
+- out, err := runcmd(append(cmd, args...)...)
++ out, err := goRun(runcmd, t.goFileName(), args...)
+ if err != nil {
+ t.err = err
+ return
+@@ -714,7 +691,7 @@ func (t *test) run() {
+ t.err = fmt.Errorf("write tempfile:%s", err)
+ return
+ }
+- cmdline := []string{"go", "tool", "compile", "-e", "-o", "a.o"}
++ cmdline := []string{findGoCmd(), "tool", "compile", "-e", "-o", "a.o"}
+ cmdline = append(cmdline, flags...)
+ cmdline = append(cmdline, tfile)
+ out, err = runcmd(cmdline...)
+@@ -741,6 +718,10 @@ func findExecCmd() []string {
+ return execCmd
+ }
+ execCmd = []string{} // avoid work the second time
++ if *target != "" {
++ execCmd = []string{"go_" + *target + "_exec"}
++ return execCmd
++ }
+ if goos == runtime.GOOS && goarch == runtime.GOARCH {
+ return execCmd
+ }
+@@ -751,6 +732,13 @@ func findExecCmd() []string {
+ return execCmd
+ }
+
++func findGoCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
+ func (t *test) String() string {
+ return filepath.Join(t.dir, t.gofile)
+ }
diff --git a/go/patch/go3.patch b/go/patch/go3.patch
new file mode 100644
index 00000000..37bd562f
--- /dev/null
+++ b/go/patch/go3.patch
@@ -0,0 +1,711 @@
+test: add runtarget action.
+
+--- test/fixedbugs/bug248.go
++++ test/fixedbugs/bug248.go
+@@ -1,5 +1,5 @@
+ // +build !nacl,!plan9,!windows
+-// run
++// runtarget
+
+ // Copyright 2009 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -8,13 +8,32 @@
+ package main
+
+ import (
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
++func goRun(cmd ...string) {
++ if *target == "" {
++ run(cmd[0], cmd[1:]...)
++ } else {
++ run("go_"+*target+"_exec", cmd...)
++ }
++}
++
+ func main() {
++ flag.Parse()
+ // TODO: If we get rid of errchk, re-enable this test on Windows.
+ errchk, err := filepath.Abs("errchk")
+ check(err)
+@@ -22,12 +41,12 @@ func main() {
+ err = os.Chdir(filepath.Join("fixedbugs", "bug248.dir"))
+ check(err)
+
+- run("go", "tool", "compile", "bug0.go")
+- run("go", "tool", "compile", "bug1.go")
+- run("go", "tool", "compile", "bug2.go")
+- run(errchk, "go", "tool", "compile", "-e", "bug3.go")
+- run("go", "tool", "link", "bug2.o")
+- run(fmt.Sprintf(".%ca.out", filepath.Separator))
++ run(goCmd(), "tool", "compile", "bug0.go")
++ run(goCmd(), "tool", "compile", "bug1.go")
++ run(goCmd(), "tool", "compile", "bug2.go")
++ run(errchk, goCmd(), "tool", "compile", "-e", "bug3.go")
++ run(goCmd(), "tool", "link", "bug2.o")
++ goRun(fmt.Sprintf(".%ca.out", filepath.Separator))
+
+ os.Remove("bug0.o")
+ os.Remove("bug1.o")
+--- test/fixedbugs/bug302.go
++++ test/fixedbugs/bug302.go
+@@ -1,5 +1,5 @@
+ // +build !nacl
+-// run
++// runtarget
+
+ // Copyright 2010 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -8,16 +8,27 @@
+ package main
+
+ import (
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
+ func main() {
+- run("go", "tool", "compile", filepath.Join("fixedbugs", "bug302.dir", "p.go"))
+- run("go", "tool", "pack", "grc", "pp.a", "p.o")
+- run("go", "tool", "compile", "-I", ".", filepath.Join("fixedbugs", "bug302.dir", "main.go"))
++ flag.Parse()
++ run(goCmd(), "tool", "compile", filepath.Join("fixedbugs", "bug302.dir", "p.go"))
++ run(goCmd(), "tool", "pack", "grc", "pp.a", "p.o")
++ run(goCmd(), "tool", "compile", "-I", ".", filepath.Join("fixedbugs", "bug302.dir", "main.go"))
+ os.Remove("p.o")
+ os.Remove("pp.a")
+ os.Remove("main.o")
+--- test/fixedbugs/bug345.go
++++ test/fixedbugs/bug345.go
+@@ -1,5 +1,5 @@
+ // +build !nacl,!plan9,!windows
+-// run
++// runtarget
+
+ // Copyright 2011 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -8,13 +8,24 @@
+ package main
+
+ import (
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
+ func main() {
++ flag.Parse()
+ // TODO: If we get rid of errchk, re-enable this test on Plan 9 and Windows.
+ errchk, err := filepath.Abs("errchk")
+ check(err)
+@@ -22,8 +33,8 @@ func main() {
+ err = os.Chdir(filepath.Join(".", "fixedbugs", "bug345.dir"))
+ check(err)
+
+- run("go", "tool", "compile", "io.go")
+- run(errchk, "go", "tool", "compile", "-e", "main.go")
++ run(goCmd(), "tool", "compile", "io.go")
++ run(errchk, goCmd(), "tool", "compile", "-e", "main.go")
+ os.Remove("io.o")
+ }
+
+--- test/fixedbugs/bug369.go
++++ test/fixedbugs/bug369.go
+@@ -1,5 +1,5 @@
+ // +build !nacl,!windows
+-// run
++// runtarget
+
+ // Copyright 2011 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -10,21 +10,40 @@
+ package main
+
+ import (
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
++func goRun(cmd ...string) {
++ if *target == "" {
++ run(cmd[0], cmd[1:]...)
++ } else {
++ run("go_"+*target+"_exec", cmd...)
++ }
++}
++
+ func main() {
++ flag.Parse()
+ err := os.Chdir(filepath.Join(".", "fixedbugs", "bug369.dir"))
+ check(err)
+
+- run("go", "tool", "compile", "-N", "-o", "slow.o", "pkg.go")
+- run("go", "tool", "compile", "-o", "fast.o", "pkg.go")
+- run("go", "tool", "compile", "-o", "main.o", "main.go")
+- run("go", "tool", "link", "-o", "a.exe", "main.o")
+- run("." + string(filepath.Separator) + "a.exe")
++ run(goCmd(), "tool", "compile", "-N", "-o", "slow.o", "pkg.go")
++ run(goCmd(), "tool", "compile", "-o", "fast.o", "pkg.go")
++ run(goCmd(), "tool", "compile", "-o", "main.o", "main.go")
++ run(goCmd(), "tool", "link", "-o", "a.exe", "main.o")
++ goRun("." + string(filepath.Separator) + "a.exe")
+
+ os.Remove("slow.o")
+ os.Remove("fast.o")
+--- test/fixedbugs/bug429_run.go
++++ test/fixedbugs/bug429_run.go
+@@ -1,5 +1,5 @@
+ // +build !nacl
+-// run
++// runtarget
+
+ // Copyright 2014 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -10,6 +10,7 @@
+ package main
+
+ import (
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+@@ -17,8 +18,27 @@ import (
+ "strings"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
++func goRun(args ...string) *exec.Cmd {
++ cmd := []string{"run"}
++ if *target != "" {
++ cmd = append(cmd, "-exec", "go_"+*target+"_exec")
++ }
++ cmd = append(cmd, args...)
++ return exec.Command(goCmd(), cmd...)
++}
++
+ func main() {
+- cmd := exec.Command("go", "run", filepath.Join("fixedbugs", "bug429.go"))
++ flag.Parse()
++ cmd := goRun(filepath.Join("fixedbugs", "bug429.go"))
+ out, err := cmd.CombinedOutput()
+ if err == nil {
+ fmt.Println("expected deadlock")
+--- test/fixedbugs/issue10607.go
++++ test/fixedbugs/issue10607.go
+@@ -1,5 +1,5 @@
+ // +build linux,!ppc64,!ppc64le,!mips64,!mips64le android
+-// run
++// runtarget
+
+ // Copyright 2015 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -11,19 +11,39 @@
+ package main
+
+ import (
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
++func goRun(args ...string) *exec.Cmd {
++ cmd := []string{"run"}
++ if *target != "" {
++ cmd = append(cmd, "-exec", "go_"+*target+"_exec")
++ }
++ cmd = append(cmd, args...)
++ return exec.Command(goCmd(), cmd...)
++}
++
+ func main() {
++ flag.Parse()
+ test("internal")
+ test("external")
+ }
+
+ func test(linkmode string) {
+- out, err := exec.Command("go", "run", "-ldflags", "-B=0x12345678 -linkmode="+linkmode, filepath.Join("fixedbugs", "issue10607a.go")).CombinedOutput()
++ out, err := goRun("-ldflags", "-B=0x12345678 -linkmode="+linkmode, filepath.Join("fixedbugs", "issue10607a.go")).CombinedOutput()
+ if err != nil {
+ fmt.Printf("BUG: linkmode=%s %v\n%s\n", linkmode, err, out)
+ os.Exit(1)
+--- test/fixedbugs/issue11771.go
++++ test/fixedbugs/issue11771.go
+@@ -1,5 +1,5 @@
+ // +build !nacl
+-// run
++// runtarget
+
+ // Copyright 2015 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -11,6 +11,7 @@ package main
+
+ import (
+ "bytes"
++ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+@@ -20,7 +21,17 @@ import (
+ "runtime"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
+ func main() {
++ flag.Parse()
+ if runtime.Compiler != "gc" {
+ return
+ }
+@@ -52,7 +63,7 @@ func x() {
+ log.Fatal(err)
+ }
+
+- cmd := exec.Command("go", "tool", "compile", "x.go")
++ cmd := exec.Command(goCmd(), "tool", "compile", "x.go")
+ cmd.Dir = dir
+ output, err := cmd.CombinedOutput()
+ if err == nil {
+--- test/fixedbugs/issue9355.go
++++ test/fixedbugs/issue9355.go
+@@ -1,4 +1,4 @@
+-// run
++// runtarget
+
+ // Copyright 2014 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -7,6 +7,7 @@
+ package main
+
+ import (
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+@@ -15,7 +16,17 @@ import (
+ "runtime"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
+ func main() {
++ flag.Parse()
+ if runtime.Compiler != "gc" || runtime.GOOS == "nacl" {
+ return
+ }
+@@ -23,7 +34,7 @@ func main() {
+ err := os.Chdir(filepath.Join("fixedbugs", "issue9355.dir"))
+ check(err)
+
+- out := run("go", "tool", "compile", "-S", "a.go")
++ out := run(goCmd(), "tool", "compile", "-S", "a.go")
+ os.Remove("a.o")
+
+ // 6g/8g print the offset as dec, but 5g/9g print the offset as hex.
+--- test/fixedbugs/issue9862_run.go
++++ test/fixedbugs/issue9862_run.go
+@@ -1,5 +1,5 @@
+ // +build !nacl
+-// run
++// runtarget
+
+ // Copyright 2015 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -10,12 +10,32 @@
+ package main
+
+ import (
++ "flag"
+ "os/exec"
+ "strings"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
++func goRun(args ...string) *exec.Cmd {
++ cmd := []string{"run"}
++ if *target != "" {
++ cmd = append(cmd, "-exec", "go_"+*target+"_exec")
++ }
++ cmd = append(cmd, args...)
++ return exec.Command(goCmd(), cmd...)
++}
++
+ func main() {
+- out, err := exec.Command("go", "run", "fixedbugs/issue9862.go").CombinedOutput()
++ flag.Parse()
++ out, err := goRun("fixedbugs/issue9862.go").CombinedOutput()
+ outstr := string(out)
+ if err == nil {
+ println("go run issue9862.go succeeded, should have failed\n", outstr)
+--- test/linkmain_run.go
++++ test/linkmain_run.go
+@@ -1,5 +1,5 @@
+ // +build !nacl
+-// run
++// runtarget
+
+ // Copyright 2014 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -10,12 +10,22 @@
+ package main
+
+ import (
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ "strings"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
+ func cleanup() {
+ os.Remove("linkmain.o")
+ os.Remove("linkmain.a")
+@@ -51,16 +61,18 @@ func runFail(cmdline string) {
+ }
+
+ func main() {
++ flag.Parse()
++
+ // helloworld.go is package main
+- run("go tool compile -o linkmain.o helloworld.go")
+- run("go tool compile -pack -o linkmain.a helloworld.go")
+- run("go tool link -o linkmain.exe linkmain.o")
+- run("go tool link -o linkmain.exe linkmain.a")
++ run(goCmd() + " tool compile -o linkmain.o helloworld.go")
++ run(goCmd() + " tool compile -pack -o linkmain.a helloworld.go")
++ run(goCmd() + " tool link -o linkmain.exe linkmain.o")
++ run(goCmd() + " tool link -o linkmain.exe linkmain.a")
+
+ // linkmain.go is not
+- run("go tool compile -o linkmain1.o linkmain.go")
+- run("go tool compile -pack -o linkmain1.a linkmain.go")
+- runFail("go tool link -o linkmain.exe linkmain1.o")
+- runFail("go tool link -o linkmain.exe linkmain1.a")
++ run(goCmd() + " tool compile -o linkmain1.o linkmain.go")
++ run(goCmd() + " tool compile -pack -o linkmain1.a linkmain.go")
++ runFail(goCmd() + " tool link -o linkmain.exe linkmain1.o")
++ runFail(goCmd() + " tool link -o linkmain.exe linkmain1.a")
+ cleanup()
+ }
+--- test/linkx_run.go
++++ test/linkx_run.go
+@@ -1,5 +1,5 @@
+ // +build !nacl
+-// run
++// runtarget
+
+ // Copyright 2014 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -11,20 +11,40 @@ package main
+
+ import (
+ "bytes"
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ "strings"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
++func goRun(args ...string) *exec.Cmd {
++ cmd := []string{"run"}
++ if *target != "" {
++ cmd = append(cmd, "-exec", "go_"+*target+"_exec")
++ }
++ cmd = append(cmd, args...)
++ return exec.Command(goCmd(), cmd...)
++}
++
+ func main() {
++ flag.Parse()
+ test(" ") // old deprecated syntax
+ test("=") // new syntax
+ }
+
+ func test(sep string) {
+ // Successful run
+- cmd := exec.Command("go", "run", "-ldflags=-X main.tbd"+sep+"hello -X main.overwrite"+sep+"trumped -X main.nosuchsymbol"+sep+"neverseen", "linkx.go")
++ cmd := goRun("-ldflags=-X main.tbd"+sep+"hello -X main.overwrite"+sep+"trumped -X main.nosuchsymbol"+sep+"neverseen", "linkx.go")
+ var out, errbuf bytes.Buffer
+ cmd.Stdout = &out
+ cmd.Stderr = &errbuf
+@@ -44,7 +64,7 @@ func test(sep string) {
+ }
+
+ // Issue 8810
+- cmd = exec.Command("go", "run", "-ldflags=-X main.tbd", "linkx.go")
++ cmd = goRun("-ldflags=-X main.tbd", "linkx.go")
+ _, err = cmd.CombinedOutput()
+ if err == nil {
+ fmt.Println("-X linker flag should not accept keys without values")
+@@ -52,7 +72,7 @@ func test(sep string) {
+ }
+
+ // Issue 9621
+- cmd = exec.Command("go", "run", "-ldflags=-X main.b=false -X main.x=42", "linkx.go")
++ cmd = goRun("-ldflags=-X main.b=false -X main.x=42", "linkx.go")
+ outx, err := cmd.CombinedOutput()
+ if err == nil {
+ fmt.Println("-X linker flag should not overwrite non-strings")
+--- test/nosplit.go
++++ test/nosplit.go
+@@ -1,5 +1,5 @@
+ // +build !nacl
+-// run
++// runtarget
+
+ // Copyright 2014 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -9,6 +9,7 @@ package main
+
+ import (
+ "bytes"
++ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+@@ -16,11 +17,28 @@ import (
+ "os/exec"
+ "path/filepath"
+ "regexp"
+- "runtime"
+ "strconv"
+ "strings"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
++func goArch() string {
++ goarch, err := exec.Command(goCmd(), "env", "GOARCH").Output()
++ if err != nil {
++ bug()
++ fmt.Printf("running go env GOARCH: %v\n", err)
++ }
++ return strings.TrimSpace(string(goarch))
++}
++
+ var tests = `
+ # These are test cases for the linker analysis that detects chains of
+ # nosplit functions that would cause a stack overflow.
+@@ -193,12 +211,13 @@ var (
+ )
+
+ func main() {
+- goarch := os.Getenv("GOARCH")
++ flag.Parse()
++ goarch := goArch()
+ if goarch == "" {
+- goarch = runtime.GOARCH
++ return
+ }
+
+- version, err := exec.Command("go", "tool", "compile", "-V").Output()
++ version, err := exec.Command(goCmd(), "tool", "compile", "-V").Output()
+ if err != nil {
+ bug()
+ fmt.Printf("running go tool compile -V: %v\n", err)
+@@ -338,7 +357,7 @@ TestCases:
+ log.Fatal(err)
+ }
+
+- cmd := exec.Command("go", "build")
++ cmd := exec.Command(goCmd(), "build")
+ cmd.Dir = dir
+ output, err := cmd.CombinedOutput()
+ if err == nil {
+--- test/run.go
++++ test/run.go
+@@ -220,6 +220,16 @@ func goRun(runcmd runCmd, goname string, args ...string) (out []byte, err error)
+ return runcmd(cmd...)
+ }
+
++func goRunTarget(runcmd runCmd, goname string, args ...string) (out []byte, err error) {
++ cmd := []string{"go_local", "run"}
++ cmd = append(cmd, goname)
++ if *target != "" {
++ cmd = append(cmd, "-target", *target)
++ }
++ cmd = append(cmd, args...)
++ return runcmd(cmd...)
++}
++
+ // skipError describes why a test was skipped.
+ type skipError string
+
+@@ -469,7 +479,7 @@ func (t *test) run() {
+ case "cmpout":
+ action = "run" // the run case already looks for <dir>/<test>.out files
+ fallthrough
+- case "compile", "compiledir", "build", "run", "runoutput", "rundir":
++ case "compile", "compiledir", "build", "run", "runtarget", "runoutput", "rundir":
+ t.action = action
+ case "errorcheck", "errorcheckdir", "errorcheckoutput":
+ t.action = action
+@@ -653,6 +663,17 @@ func (t *test) run() {
+ t.err = fmt.Errorf("incorrect output\n%s", out)
+ }
+
++ case "runtarget":
++ useTmp = false
++ out, err := goRunTarget(runcmd, t.goFileName(), args...)
++ if err != nil {
++ t.err = err
++ return
++ }
++ if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
++ t.err = fmt.Errorf("incorrect output\n%s", out)
++ }
++
+ case "runoutput":
+ rungatec <- true
+ defer func() {
+--- test/sinit_run.go
++++ test/sinit_run.go
+@@ -1,5 +1,5 @@
+ // +build !nacl
+-// run
++// runtarget
+
+ // Copyright 2014 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
+@@ -11,13 +11,24 @@ package main
+
+ import (
+ "bytes"
++ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
+ func main() {
+- cmd := exec.Command("go", "tool", "compile", "-S", "sinit.go")
++ flag.Parse()
++ cmd := exec.Command(goCmd(), "tool", "compile", "-S", "sinit.go")
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ fmt.Println(string(out))
diff --git a/go/patch/go4.patch b/go/patch/go4.patch
new file mode 100644
index 00000000..1c96c093
--- /dev/null
+++ b/go/patch/go4.patch
@@ -0,0 +1,101 @@
+runtime, crypto/x509: add -target flag.
+
+--- src/crypto/x509/x509_test.go
++++ src/crypto/x509/x509_test.go
+@@ -19,6 +19,7 @@ import (
+ "encoding/hex"
+ "encoding/pem"
+ "fmt"
++ "flag"
+ "internal/testenv"
+ "math/big"
+ "net"
+@@ -28,6 +29,8 @@ import (
+ "time"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
+ func TestParsePKCS1PrivateKey(t *testing.T) {
+ block, _ := pem.Decode([]byte(pemPrivateKey))
+ priv, err := ParsePKCS1PrivateKey(block.Bytes)
+@@ -862,7 +865,13 @@ func TestParsePEMCRL(t *testing.T) {
+ func TestImports(t *testing.T) {
+ testenv.MustHaveGoRun(t)
+
+- if err := exec.Command("go", "run", "x509_test_import.go").Run(); err != nil {
++ var cmd *exec.Cmd
++ if *target == "" {
++ cmd = exec.Command("go", "run", "x509_test_import.go")
++ } else {
++ cmd = exec.Command("go_"+*target, "run", "-exec", "go_"+*target+"_exec", "x509_test_import.go")
++ }
++ if err := cmd.Run(); err != nil {
+ t.Errorf("failed to run x509_test_import.go: %s", err)
+ }
+ }
+--- src/runtime/crash_test.go
++++ src/runtime/crash_test.go
+@@ -5,6 +5,7 @@
+ package runtime_test
+
+ import (
++ "flag"
+ "fmt"
+ "internal/testenv"
+ "io/ioutil"
+@@ -18,6 +19,25 @@ import (
+ "testing"
+ )
+
++var target = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
++
++func goCmd() string {
++ if *target != "" {
++ return "go_" + *target
++ }
++ return "go"
++}
++
++func goExecCmd(name string, arg ...string) *exec.Cmd {
++ var cmd []string
++ if *target != "" {
++ cmd = append(cmd, "go_"+*target+"_exec")
++ }
++ cmd = append(cmd, name)
++ cmd = append(cmd, arg...)
++ return exec.Command(cmd[0], cmd[1:]...)
++}
++
+ var toRemove []string
+
+ func TestMain(m *testing.M) {
+@@ -65,7 +85,7 @@ func runTestProg(t *testing.T, binary, name string) string {
+ if err != nil {
+ t.Fatal(err)
+ }
+- got, _ := testEnv(exec.Command(exe, name)).CombinedOutput()
++ got, _ := testEnv(goExecCmd(exe, name)).CombinedOutput()
+ return string(got)
+ }
+
+@@ -92,7 +112,7 @@ func buildTestProg(t *testing.T, binary string) (string, error) {
+ }
+
+ exe := filepath.Join(testprog.dir, binary+".exe")
+- cmd := exec.Command("go", "build", "-o", exe)
++ cmd := exec.Command(goCmd(), "build", "-o", exe)
+ cmd.Dir = "testdata/" + binary
+ out, err := testEnv(cmd).CombinedOutput()
+ if err != nil {
+--- src/runtime/crash_unix_test.go
++++ src/runtime/crash_unix_test.go
+@@ -157,7 +157,7 @@ func TestSignalExitStatus(t *testing.T) {
+ if err != nil {
+ t.Fatal(err)
+ }
+- err = testEnv(exec.Command(exe, "SignalExitStatus")).Run()
++ err = testEnv(goExecCmd(exe, "SignalExitStatus")).Run()
+ if err == nil {
+ t.Error("test program succeeded unexpectedly")
+ } else if ee, ok := err.(*exec.ExitError); !ok {
diff --git a/go/patch/go5.patch b/go/patch/go5.patch
new file mode 100644
index 00000000..fa656586
--- /dev/null
+++ b/go/patch/go5.patch
@@ -0,0 +1,198 @@
+misc/cgo/testcshared: add support for -target.
+
+--- misc/cgo/testcshared/test.bash
++++ misc/cgo/testcshared/test.bash
+@@ -14,9 +14,23 @@ if [ ! -f src/libgo/libgo.go ]; then
+ exit 1
+ fi
+
+-goos=$(go env GOOS)
+-goarch=$(go env GOARCH)
+-goroot=$(go env GOROOT)
++function target()
++ {
++ [[ -n "${target}" ]]
++ }
++
++function go_target()
++ {
++ if target; then
++ go_${target} "$@"
++ else
++ go "$@"
++ fi
++ }
++
++goos=$(go_target env GOOS)
++goarch=$(go_target env GOARCH)
++goroot=$(go_target env GOROOT)
+ if [ ! -d "$goroot" ]; then
+ echo 'misc/cgo/testcshared/test.bash cannnot find GOROOT' 1>&2
+ echo '$GOROOT:' "$GOROOT" 1>&2
+@@ -31,8 +45,10 @@ if [ "${goos}" == "darwin" ]; then
+ installdir=pkg/${goos}_${goarch}_testcshared
+ fi
+
+-# Temporary directory on the android device.
+-androidpath=/data/local/tmp/testcshared-$$
++# Temporary directory on the android/chromeos device.
++if target; then
++ remotepath=$(target_tmpdir)/testcshared-$$
++fi
+
+ function cleanup() {
+ rm -f libgo.$libext libgo2.$libext libgo4.$libext libgo5.$libext
+@@ -40,37 +56,33 @@ function cleanup() {
+ rm -f testp testp2 testp3 testp4 testp5
+ rm -rf pkg "${goroot}/${installdir}"
+
+- if [ "$goos" == "android" ]; then
+- adb shell rm -rf "$androidpath"
++ if target; then
++ target_sh "${target}" "rm -rf $remotepath"
+ fi
+ }
+ trap cleanup EXIT
+
+-if [ "$goos" == "android" ]; then
+- adb shell mkdir -p "$androidpath"
++if target; then
++ target_sh "${target}" "mkdir -p $remotepath"
+ fi
+
+ function run() {
+- case "$goos" in
+- "android")
++ if target; then
+ local args=$@
+- output=$(adb shell "cd ${androidpath}; $@")
+- output=$(echo $output|tr -d '\r')
++ output=$(target_sh "${target}" "cd ${remotepath}; $@")
+ case $output in
+ *PASS) echo "PASS";;
+ *) echo "$output";;
+ esac
+- ;;
+- *)
++ else
+ echo $(env $@)
+- ;;
+- esac
++ fi
+ }
+
+ function binpush() {
+ bin=${1}
+- if [ "$goos" == "android" ]; then
+- adb push "$bin" "${androidpath}/${bin}" 2>/dev/null
++ if target; then
++ target_cp "$bin" "${target}:${remotepath}/${bin}"
+ fi
+ }
+
+@@ -84,9 +96,9 @@ if [ "$goos" == "darwin" ]; then
+ fi
+
+ # Create the header files.
+-GOPATH=$(pwd) go install -buildmode=c-shared $suffix libgo
++GOPATH=$(pwd) go_target install -buildmode=c-shared $suffix libgo
+
+-GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo.$libext src/libgo/libgo.go
++GOPATH=$(pwd) go_target build -buildmode=c-shared $suffix -o libgo.$libext src/libgo/libgo.go
+ binpush libgo.$libext
+
+ if [ "$goos" == "linux" ] || [ "$goos" == "android" ] ; then
+@@ -96,8 +108,8 @@ if [ "$goos" == "linux" ] || [ "$goos" == "android" ] ; then
+ fi
+ fi
+
+-GOGCCFLAGS=$(go env GOGCCFLAGS)
+-if [ "$goos" == "android" ]; then
++GOGCCFLAGS=$(go_target env GOGCCFLAGS)
++if target; then
+ GOGCCFLAGS="${GOGCCFLAGS} -pie"
+ fi
+
+@@ -105,7 +117,7 @@ status=0
+
+ # test0: exported symbols in shared lib are accessible.
+ # TODO(iant): using _shared here shouldn't really be necessary.
+-$(go env CC) ${GOGCCFLAGS} -I ${installdir} -o testp main0.c libgo.$libext
++$(go_target env CC) ${GOGCCFLAGS} -I ${installdir} -o testp main0.c libgo.$libext
+ binpush testp
+
+ output=$(run LD_LIBRARY_PATH=. ./testp)
+@@ -115,7 +127,7 @@ if [ "$output" != "PASS" ]; then
+ fi
+
+ # test1: shared library can be dynamically loaded and exported symbols are accessible.
+-$(go env CC) ${GOGCCFLAGS} -o testp main1.c -ldl
++$(go_target env CC) ${GOGCCFLAGS} -o testp main1.c -ldl
+ binpush testp
+ output=$(run ./testp ./libgo.$libext)
+ if [ "$output" != "PASS" ]; then
+@@ -124,13 +136,13 @@ if [ "$output" != "PASS" ]; then
+ fi
+
+ # test2: tests libgo2 which does not export any functions.
+-GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo2.$libext libgo2
++GOPATH=$(pwd) go_target build -buildmode=c-shared $suffix -o libgo2.$libext libgo2
+ binpush libgo2.$libext
+ linkflags="-Wl,--no-as-needed"
+ if [ "$goos" == "darwin" ]; then
+ linkflags=""
+ fi
+-$(go env CC) ${GOGCCFLAGS} -o testp2 main2.c $linkflags libgo2.$libext
++$(go_target env CC) ${GOGCCFLAGS} -o testp2 main2.c $linkflags libgo2.$libext
+ binpush testp2
+ output=$(run LD_LIBRARY_PATH=. ./testp2)
+ if [ "$output" != "PASS" ]; then
+@@ -138,9 +150,9 @@ if [ "$output" != "PASS" ]; then
+ status=1
+ fi
+
+-# test3: tests main.main is exported on android.
+-if [ "$goos" == "android" ]; then
+- $(go env CC) ${GOGCCFLAGS} -o testp3 main3.c -ldl
++# test3: tests main.main is exported on android/chromeos.
++if target; then
++ $(go_target env CC) ${GOGCCFLAGS} -o testp3 main3.c -ldl
+ binpush testp3
+ output=$(run ./testp ./libgo.so)
+ if [ "$output" != "PASS" ]; then
+@@ -150,14 +162,14 @@ if [ "$goos" == "android" ]; then
+ fi
+
+ # test4: tests signal handlers
+-GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo4.$libext libgo4
++GOPATH=$(pwd) go_target build -buildmode=c-shared $suffix -o libgo4.$libext libgo4
+ binpush libgo4.$libext
+-$(go env CC) ${GOGCCFLAGS} -pthread -o testp4 main4.c -ldl
++$(go_target env CC) ${GOGCCFLAGS} -pthread -o testp4 main4.c -ldl
+ binpush testp4
+ output=$(run ./testp4 ./libgo4.$libext 2>&1)
+ if test "$output" != "PASS"; then
+ echo "FAIL test4 got ${output}"
+- if test "$goos" != "android"; then
++ if ! target; then
+ echo "re-running test4 in verbose mode"
+ ./testp4 ./libgo4.$libext verbose
+ fi
+@@ -165,14 +177,14 @@ if test "$output" != "PASS"; then
+ fi
+
+ # test5: tests signal handlers with os/signal.Notify
+-GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo5.$libext libgo5
++GOPATH=$(pwd) go_target build -buildmode=c-shared $suffix -o libgo5.$libext libgo5
+ binpush libgo5.$libext
+-$(go env CC) ${GOGCCFLAGS} -pthread -o testp5 main5.c -ldl
++$(go_target env CC) ${GOGCCFLAGS} -pthread -o testp5 main5.c -ldl
+ binpush testp5
+ output=$(run ./testp5 ./libgo5.$libext 2>&1)
+ if test "$output" != "PASS"; then
+ echo "FAIL test5 got ${output}"
+- if test "$goos" != "android"; then
++ if ! target; then
+ echo "re-running test5 in verbose mode"
+ ./testp5 ./libgo5.$libext verbose
+ fi
diff --git a/go/patch/go6.patch b/go/patch/go6.patch
new file mode 100644
index 00000000..7f1e4c0e
--- /dev/null
+++ b/go/patch/go6.patch
@@ -0,0 +1,65 @@
+runtime: deadlock detection does not work when using external linker.
+
+--- src/runtime/crash_test.go
++++ src/runtime/crash_test.go
+@@ -177,22 +177,27 @@ func testDeadlock(t *testing.T, name string) {
+ }
+
+ func TestSimpleDeadlock(t *testing.T) {
++ t.Skip("deadlock detection fails with external linker")
+ testDeadlock(t, "SimpleDeadlock")
+ }
+
+ func TestInitDeadlock(t *testing.T) {
++ t.Skip("deadlock detection fails with external linker")
+ testDeadlock(t, "InitDeadlock")
+ }
+
+ func TestLockedDeadlock(t *testing.T) {
++ t.Skip("deadlock detection fails with external linker")
+ testDeadlock(t, "LockedDeadlock")
+ }
+
+ func TestLockedDeadlock2(t *testing.T) {
++ t.Skip("deadlock detection fails with external linker")
+ testDeadlock(t, "LockedDeadlock2")
+ }
+
+ func TestGoexitDeadlock(t *testing.T) {
++ t.Skip("deadlock detection fails with external linker")
+ output := runTestProg(t, "testprog", "GoexitDeadlock")
+ want := "no goroutines (main called runtime.Goexit) - deadlock!"
+ if !strings.Contains(output, want) {
+@@ -229,6 +234,7 @@ panic: again
+ }
+
+ func TestGoexitCrash(t *testing.T) {
++ t.Skip("deadlock detection fails with external linker")
+ output := runTestProg(t, "testprog", "GoexitExit")
+ want := "no goroutines (main called runtime.Goexit) - deadlock!"
+ if !strings.Contains(output, want) {
+@@ -285,6 +291,7 @@ func TestBreakpoint(t *testing.T) {
+ }
+
+ func TestGoexitInPanic(t *testing.T) {
++ t.Skip("deadlock detection fails with external linker")
+ // see issue 8774: this code used to trigger an infinite recursion
+ output := runTestProg(t, "testprog", "GoexitInPanic")
+ want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
+@@ -303,6 +310,7 @@ func TestPanicAfterGoexit(t *testing.T) {
+ }
+
+ func TestRecoveredPanicAfterGoexit(t *testing.T) {
++ t.Skip("deadlock detection fails with external linker")
+ output := runTestProg(t, "testprog", "RecoveredPanicAfterGoexit")
+ want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
+ if !strings.HasPrefix(output, want) {
+--- test/fixedbugs/bug429_run.go
++++ test/fixedbugs/bug429_run.go
+@@ -1,5 +1,5 @@
+ // +build !nacl
+-// runtarget
++// skip
+
+ // Copyright 2014 The Go Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style
diff --git a/go/patch/go7.patch b/go/patch/go7.patch
new file mode 100644
index 00000000..7b769cf4
--- /dev/null
+++ b/go/patch/go7.patch
@@ -0,0 +1,139 @@
+all: disable some tests that take a long time or allocate a lot of memory.
+
+--- src/encoding/gob/encoder_test.go
++++ src/encoding/gob/encoder_test.go
+@@ -1003,10 +1003,7 @@ func TestBadData(t *testing.T) {
+
+ // TestHugeWriteFails tests that enormous messages trigger an error.
+ func TestHugeWriteFails(t *testing.T) {
+- if testing.Short() {
+- // Requires allocating a monster, so don't do this from all.bash.
+- t.Skip("skipping huge allocation in short mode")
+- }
++ t.Skip("skipping test due to huge memory requirement")
+ huge := make([]byte, tooBig)
+ huge[0] = 7 // Make sure it's not all zeros.
+ buf := new(bytes.Buffer)
+--- src/math/big/float_test.go
++++ src/math/big/float_test.go
+@@ -1428,10 +1428,7 @@ func TestFloatQuo(t *testing.T) {
+ // TestFloatQuoSmoke tests all divisions x/y for values x, y in the range [-n, +n];
+ // it serves as a smoke test for basic correctness of division.
+ func TestFloatQuoSmoke(t *testing.T) {
+- n := 1000
+- if testing.Short() {
+- n = 10
+- }
++ n := 10
+
+ const dprec = 3 // max. precision variation
+ const prec = 10 + dprec // enough bits to hold n precisely
+--- src/math/big/rat_test.go
++++ src/math/big/rat_test.go
+@@ -430,10 +430,7 @@ func TestFloat64Distribution(t *testing.T) {
+ 9,
+ 11,
+ }
+- var winc, einc = uint64(1), 1 // soak test (~75s on x86-64)
+- if testing.Short() {
+- winc, einc = 10, 500 // quick test (~12ms on x86-64)
+- }
++ var winc, einc = uint64(10), 500
+
+ for _, sign := range "+-" {
+ for _, a := range add {
+--- src/math/big/ratconv_test.go
++++ src/math/big/ratconv_test.go
+@@ -344,9 +344,7 @@ func isFinite(f float64) bool {
+ func TestFloat32SpecialCases(t *testing.T) {
+ for _, input := range float64inputs {
+ if strings.HasPrefix(input, "long:") {
+- if testing.Short() {
+- continue
+- }
++ continue
+ input = input[len("long:"):]
+ }
+
+@@ -400,9 +398,7 @@ func TestFloat32SpecialCases(t *testing.T) {
+ func TestFloat64SpecialCases(t *testing.T) {
+ for _, input := range float64inputs {
+ if strings.HasPrefix(input, "long:") {
+- if testing.Short() {
+- continue
+- }
++ continue
+ input = input[len("long:"):]
+ }
+
+--- src/net/dial_test.go
++++ src/net/dial_test.go
+@@ -77,10 +77,7 @@ func TestSelfConnect(t *testing.T) {
+ l.Close()
+
+ // Try to connect to that address repeatedly.
+- n := 100000
+- if testing.Short() {
+- n = 1000
+- }
++ n := 1000
+ switch runtime.GOOS {
+ case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "solaris", "windows":
+ // Non-Linux systems take a long time to figure
+--- src/runtime/fastlog2_test.go
++++ src/runtime/fastlog2_test.go
+@@ -16,11 +16,7 @@ func TestFastLog2(t *testing.T) {
+ const randomBitCount = 26
+ var e float64
+
+- inc := 1
+- if testing.Short() {
+- // Check 1K total values, down from 64M.
+- inc = 1 << 16
+- }
++ inc := 1 << 16
+ for i := 1; i < 1<<randomBitCount; i += inc {
+ l, fl := math.Log2(float64(i)), runtime.Fastlog2(float64(i))
+ d := l - fl
+--- src/runtime/hash_test.go
++++ src/runtime/hash_test.go
+@@ -126,9 +126,7 @@ func TestSmhasherZeros(t *testing.T) {
+
+ // Strings with up to two nonzero bytes all have distinct hashes.
+ func TestSmhasherTwoNonzero(t *testing.T) {
+- if testing.Short() {
+- t.Skip("Skipping in short mode")
+- }
++ t.Skip("skipping test due to huge memory requirement")
+ h := newHashSet()
+ for n := 2; n <= 16; n++ {
+ twoNonZero(h, n)
+@@ -229,9 +227,7 @@ func setbits(h *HashSet, b []byte, i int, k int) {
+ // Test all possible combinations of n blocks from the set s.
+ // "permutation" is a bad name here, but it is what Smhasher uses.
+ func TestSmhasherPermutation(t *testing.T) {
+- if testing.Short() {
+- t.Skip("Skipping in short mode")
+- }
++ t.Skip("skipping test due to huge memory requirement")
+ permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7}, 8)
+ permutation(t, []uint32{0, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 8)
+ permutation(t, []uint32{0, 1}, 20)
+--- src/runtime/pprof/pprof_test.go
++++ src/runtime/pprof/pprof_test.go
+@@ -257,14 +257,7 @@ func profileOk(t *testing.T, need []string, prof bytes.Buffer, duration time.Dur
+ func TestCPUProfileWithFork(t *testing.T) {
+ testenv.MustHaveExec(t)
+
+- heap := 1 << 30
+- if runtime.GOOS == "android" {
+- // Use smaller size for Android to avoid crash.
+- heap = 100 << 20
+- }
+- if testing.Short() {
+- heap = 100 << 20
+- }
++ heap := 100 << 20
+ // This makes fork slower.
+ garbage := make([]byte, heap)
+ // Need to touch the slice, otherwise it won't be paged in.
diff --git a/go/test_go b/go/test_go
new file mode 100755
index 00000000..3740c1b7
--- /dev/null
+++ b/go/test_go
@@ -0,0 +1,88 @@
+#!/bin/bash
+
+# This script runs tests for the Go toolchain on target devices.
+# It can be used for both ChromeOS and Android targets.
+#
+# Many of the test drivers that come from upstream do not support
+# cross-compiling and running the tests remotely. The patches in
+# the ./patch/ directory must be applied to the upstream sources
+# to add this support.
+#
+# Usage: test_go [-v] [-vv] [-full] <target>...
+# -v: enable verbose test output from compiler tests.
+# -v: enable verbose test output from standard library tests.
+# -full: run all standard library tests (without the -short flag).
+
+verbose_run_test=""
+verbose_go_test=""
+testflags="-short"
+while [[ "$1" == -* ]]
+do
+ case "$1" in
+ -v) verbose_run_test="-v" ;;
+ -vv) verbose_go_test="-v" ;;
+ -full) testflags="-timeout=2h" ;;
+ *) echo "unrecognized flag: $1" ;;
+ esac
+ shift
+done
+
+go_local build -o runtest test/run.go
+runtest="${PWD}/runtest"
+
+function run_test()
+ {
+ GOOS="$(go_${target} env GOOS)" GOARCH="$(go_${target} env GOARCH)" ${runtest} -n=1 ${verbose_run_test} -show_skips -summary -target="${target}" "$@"
+ }
+
+function go_test()
+ {
+ go_${target} test -p=1 ${verbose_go_test} -exec="go_${target}_exec" ${testflags} "$@"
+ }
+
+function go_test_target()
+ {
+ go_local test -p=1 ${verbose_go_test} ${testflags} "$@" -target="${target}"
+ }
+
+for target in "$@"
+do
+ echo
+ echo "## ${target}"
+
+ echo
+ echo "# test"
+ (cd test && run_test)
+
+ echo
+ echo "# std"
+ go_test std
+
+ echo
+ echo "# GOMAXPROCS=2 -cpu=1,2,4 runtime"
+ GOMAXPROCS=2 go_test -cpu=1,2,4 runtime
+
+ echo
+ echo "# -cpu=10 sync"
+ go_test -cpu=10 sync
+
+ echo
+ echo "# runtime crypto/x509 -target=${target}"
+ go_test_target runtime crypto/x509
+
+ echo
+ echo "# misc/cgo/{stdio,life}"
+ run_test misc/cgo/{stdio,life}
+
+ echo
+ echo "# misc/cgo/{test,testtls,nocgo}"
+ GOTRACEBACK=2 go_test ./misc/cgo/{test,testtls,nocgo}
+
+ echo
+ echo "# misc/cgo/testcshared"
+ (cd misc/cgo/testcshared && target="${target}" ./test.bash)
+
+ echo
+ echo "# misc/cgo/testsigfwd"
+ (cd misc/cgo/testsigfwd && go_${target} run -exec="go_${target}_exec" main.go)
+done