1diff --git test/run.go test/run.go
2index 22ec7576f8..ac5d3c3e8d 100644
3--- test/run.go
4+++ test/run.go
5@@ -39,9 +39,9 @@ var (
6 	summary        = flag.Bool("summary", false, "show summary of results")
7 	showSkips      = flag.Bool("show_skips", false, "show skipped tests")
8 	runSkips       = flag.Bool("run_skips", false, "run skipped tests (ignore skip and build tags)")
9-	linkshared     = flag.Bool("linkshared", false, "")
10 	updateErrors   = flag.Bool("update_errors", false, "update error messages in test file based on compiler output")
11 	runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run")
12+        target         = flag.String("target", "", "if non empty, use 'go_target' to compile test files and 'go_target_exec' to run the binaries")
13
14 	shard  = flag.Int("shard", 0, "shard index to run. Only applicable if -shards is non-zero.")
15 	shards = flag.Int("shards", 0, "number of shards. If 0, all tests are run. This is used by the continuous build.")
16@@ -194,21 +194,15 @@ func goFiles(dir string) []string {
17 type runCmd func(...string) ([]byte, error)
18
19 func compileFile(runcmd runCmd, longname string, flags []string) (out []byte, err error) {
20-	cmd := []string{"go", "tool", "compile", "-e"}
21+	cmd := []string{findGoCmd(), "tool", "compile", "-e"}
22 	cmd = append(cmd, flags...)
23-	if *linkshared {
24-		cmd = append(cmd, "-dynlink", "-installsuffix=dynlink")
25-	}
26 	cmd = append(cmd, longname)
27 	return runcmd(cmd...)
28 }
29
30 func compileInDir(runcmd runCmd, dir string, flags []string, names ...string) (out []byte, err error) {
31-	cmd := []string{"go", "tool", "compile", "-e", "-D", ".", "-I", "."}
32+	cmd := []string{findGoCmd(), "tool", "compile", "-e", "-D", ".", "-I", "."}
33 	cmd = append(cmd, flags...)
34-	if *linkshared {
35-		cmd = append(cmd, "-dynlink", "-installsuffix=dynlink")
36-	}
37 	for _, name := range names {
38 		cmd = append(cmd, filepath.Join(dir, name))
39 	}
40@@ -217,15 +211,24 @@ func compileInDir(runcmd runCmd, dir string, flags []string, names ...string) (o
41
42 func linkFile(runcmd runCmd, goname string) (err error) {
43 	pfile := strings.Replace(goname, ".go", ".o", -1)
44-	cmd := []string{"go", "tool", "link", "-w", "-o", "a.exe", "-L", "."}
45-	if *linkshared {
46-		cmd = append(cmd, "-linkshared", "-installsuffix=dynlink")
47-	}
48-	cmd = append(cmd, pfile)
49-	_, err = runcmd(cmd...)
50+	cmd := []string{findGoCmd, "tool", "link", "-w", "-o", "a.exe", "-L", "."}
51+	_, err = runcmd(findGoCmd(), "tool", "link", "-w", "-o", "a.exe", "-L", ".", pfile)
52 	return
53 }
54
55+
56+func goRun(runcmd runCmd, flags []string, goname string, args ...string) (out []byte, err error) {
57+        cmd := []string{findGoCmd(), "run", goGcflags()}
58+        if len(findExecCmd()) > 0 {
59+                cmd = append(cmd, "-exec")
60+                cmd = append(cmd, findExecCmd()...)
61+        }
62+        cmd = append(cmd, flags...)
63+        cmd = append(cmd, goname)
64+        cmd = append(cmd, args...)
65+        return runcmd(cmd...)
66+}
67+
68 // skipError describes why a test was skipped.
69 type skipError string
70
71@@ -595,7 +598,7 @@ func (t *test) run() {
72
73 	case "errorcheck":
74 		// TODO(gri) remove need for -C (disable printing of columns in error messages)
75-		cmdline := []string{"go", "tool", "compile", "-C", "-e", "-o", "a.o"}
76+		cmdline := []string{findGoCmd(), "tool", "compile", "-C", "-e", "-o", "a.o"}
77 		// No need to add -dynlink even if linkshared if we're just checking for errors...
78 		cmdline = append(cmdline, flags...)
79 		cmdline = append(cmdline, long)
80@@ -709,7 +712,7 @@ func (t *test) run() {
81 		}
82
83 	case "build":
84-		_, err := runcmd("go", "build", goGcflags(), "-o", "a.exe", long)
85+		_, err := runcmd(findGoCmd(), "build", goGcflags(), "-o", "a.exe", long)
86 		if err != nil {
87 			t.err = err
88 		}
89@@ -735,7 +738,7 @@ func (t *test) run() {
90
91 		}
92 		var objs []string
93-		cmd := []string{"go", "tool", "compile", "-e", "-D", ".", "-I", ".", "-o", "go.o"}
94+		cmd := []string{findGoCmd(), "tool", "compile", "-e", "-D", ".", "-I", ".", "-o", "go.o"}
95 		if len(asms) > 0 {
96 			cmd = append(cmd, "-asmhdr", "go_asm.h")
97 		}
98@@ -749,7 +752,7 @@ func (t *test) run() {
99 		}
100 		objs = append(objs, "go.o")
101 		if len(asms) > 0 {
102-			cmd = []string{"go", "tool", "asm", "-e", "-I", ".", "-o", "asm.o"}
103+			cmd = []string{findGoCmd(), "tool", "asm", "-e", "-I", ".", "-o", "asm.o"}
104 			for _, file := range asms {
105 				cmd = append(cmd, filepath.Join(longdir, file.Name()))
106 			}
107@@ -760,14 +763,14 @@ func (t *test) run() {
108 			}
109 			objs = append(objs, "asm.o")
110 		}
111-		cmd = []string{"go", "tool", "pack", "c", "all.a"}
112+		cmd = []string{findGoCmd(), "tool", "pack", "c", "all.a"}
113 		cmd = append(cmd, objs...)
114 		_, err = runcmd(cmd...)
115 		if err != nil {
116 			t.err = err
117 			break
118 		}
119-		cmd = []string{"go", "tool", "link", "all.a"}
120+		cmd = []string{findGoCmd(), "tool", "link", "-o", "a.exe", "all.a"}
121 		_, err = runcmd(cmd...)
122 		if err != nil {
123 			t.err = err
124@@ -777,10 +780,7 @@ func (t *test) run() {
125 	case "buildrun": // build binary, then run binary, instead of go run. Useful for timeout tests where failure mode is infinite loop.
126 		// TODO: not supported on NaCl
127 		useTmp = true
128-		cmd := []string{"go", "build", goGcflags(), "-o", "a.exe"}
129-		if *linkshared {
130-			cmd = append(cmd, "-linkshared")
131-		}
132+		cmd := []string{findGoCmd(), "build", goGcflags(), "-o", "a.exe"}
133 		longdirgofile := filepath.Join(filepath.Join(cwd, t.dir), t.gofile)
134 		cmd = append(cmd, flags...)
135 		cmd = append(cmd, longdirgofile)
136@@ -789,7 +789,12 @@ func (t *test) run() {
137 			t.err = err
138 			return
139 		}
140-		cmd = []string{"./a.exe"}
141+                cmd = []string{}
142+                if len(findExecCmd()) > 0 {
143+                        cmd = append(cmd, findExecCmd()...)
144+                }
145+                cmd = append(cmd, "./a.exe")
146+
147 		out, err = runcmd(append(cmd, args...)...)
148 		if err != nil {
149 			t.err = err
150@@ -802,38 +807,7 @@ func (t *test) run() {
151
152 	case "run":
153 		useTmp = false
154-		var out []byte
155-		var err error
156-		if len(flags)+len(args) == 0 && goGcflags() == "" && !*linkshared {
157-			// If we're not using special go command flags,
158-			// skip all the go command machinery.
159-			// This avoids any time the go command would
160-			// spend checking whether, for example, the installed
161-			// package runtime is up to date.
162-			// Because we run lots of trivial test programs,
163-			// the time adds up.
164-			pkg := filepath.Join(t.tempDir, "pkg.a")
165-			if _, err := runcmd("go", "tool", "compile", "-o", pkg, t.goFileName()); err != nil {
166-				t.err = err
167-				return
168-			}
169-			exe := filepath.Join(t.tempDir, "test.exe")
170-			cmd := []string{"go", "tool", "link", "-s", "-w"}
171-			cmd = append(cmd, "-o", exe, pkg)
172-			if _, err := runcmd(cmd...); err != nil {
173-				t.err = err
174-				return
175-			}
176-			out, err = runcmd(append([]string{exe}, args...)...)
177-		} else {
178-			cmd := []string{"go", "run", goGcflags()}
179-			if *linkshared {
180-				cmd = append(cmd, "-linkshared")
181-			}
182-			cmd = append(cmd, flags...)
183-			cmd = append(cmd, t.goFileName())
184-			out, err = runcmd(append(cmd, args...)...)
185-		}
186+		out, err := goRun(runcmd, flags, t.goFileName(), args...)
187 		if err != nil {
188 			t.err = err
189 			return
190@@ -848,12 +822,7 @@ func (t *test) run() {
191 			<-rungatec
192 		}()
193 		useTmp = false
194-		cmd := []string{"go", "run", goGcflags()}
195-		if *linkshared {
196-			cmd = append(cmd, "-linkshared")
197-		}
198-		cmd = append(cmd, t.goFileName())
199-		out, err := runcmd(append(cmd, args...)...)
200+		out, err := goRun(runcmd, nil, t.goFileName(), args...)
201 		if err != nil {
202 			t.err = err
203 			return
204@@ -863,12 +832,7 @@ func (t *test) run() {
205 			t.err = fmt.Errorf("write tempfile:%s", err)
206 			return
207 		}
208-		cmd = []string{"go", "run", goGcflags()}
209-		if *linkshared {
210-			cmd = append(cmd, "-linkshared")
211-		}
212-		cmd = append(cmd, tfile)
213-		out, err = runcmd(cmd...)
214+		out, err = goRun(runcmd, nil, tfile)
215 		if err != nil {
216 			t.err = err
217 			return
218@@ -879,12 +843,7 @@ func (t *test) run() {
219
220 	case "errorcheckoutput":
221 		useTmp = false
222-		cmd := []string{"go", "run", goGcflags()}
223-		if *linkshared {
224-			cmd = append(cmd, "-linkshared")
225-		}
226-		cmd = append(cmd, t.goFileName())
227-		out, err := runcmd(append(cmd, args...)...)
228+		out, err := goRun(runcmd, nil, t.goFileName(), args...)
229 		if err != nil {
230 			t.err = err
231 			return
232@@ -895,7 +854,7 @@ func (t *test) run() {
233 			t.err = fmt.Errorf("write tempfile:%s", err)
234 			return
235 		}
236-		cmdline := []string{"go", "tool", "compile", "-e", "-o", "a.o"}
237+		cmdline := []string{findGoCmd(), "tool", "compile", "-e", "-o", "a.o"}
238 		cmdline = append(cmdline, flags...)
239 		cmdline = append(cmdline, tfile)
240 		out, err = runcmd(cmdline...)
241@@ -922,6 +881,11 @@ func findExecCmd() []string {
242 		return execCmd
243 	}
244 	execCmd = []string{} // avoid work the second time
245+        if *target != "" {
246+                execCmd = []string{"go_" + *target + "_exec"}
247+                return execCmd
248+        }
249+
250 	if goos == runtime.GOOS && goarch == runtime.GOARCH {
251 		return execCmd
252 	}
253@@ -932,6 +896,14 @@ func findExecCmd() []string {
254 	return execCmd
255 }
256
257+func findGoCmd() string {
258+        if *target != "" {
259+                return "go_" + *target
260+        }
261+        return "go"
262+}
263+
264+
265 func (t *test) String() string {
266 	return filepath.Join(t.dir, t.gofile)
267 }
268