build: make nacl pass

Add nacl.bash, the NaCl version of all.bash.
It's a separate script because it builds a variant of package syscall
with a large zip file embedded in it, containing all the input files
needed for tests.

Disable various tests new since the last round, mostly the ones using os/exec.

Fixes #7945.

LGTM=dave
R=golang-codereviews, remyoudompheng, dave, bradfitz
CC=golang-codereviews
https://golang.org/cl/100590044
diff --git a/src/all.bash b/src/all.bash
index 488ca46..5d994d3 100755
--- a/src/all.bash
+++ b/src/all.bash
@@ -9,7 +9,7 @@
 	exit 1
 fi
 OLDPATH="$PATH"
-. ./make.bash --no-banner
+. ./make.bash "$@" --no-banner
 bash run.bash --no-rebuild
 PATH="$OLDPATH"
 $GOTOOLDIR/dist banner  # print build info
diff --git a/src/cmd/addr2line/addr2line_test.go b/src/cmd/addr2line/addr2line_test.go
index 1b7f8b5..b278d08 100644
--- a/src/cmd/addr2line/addr2line_test.go
+++ b/src/cmd/addr2line/addr2line_test.go
@@ -92,6 +92,10 @@
 
 // This is line 93. The test depends on that.
 func TestAddr2Line(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	syms := loadSyms(t)
 
 	tmpDir, err := ioutil.TempDir("", "TestAddr2Line")
diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go
index eab0732..f4e47a4 100644
--- a/src/cmd/nm/nm_test.go
+++ b/src/cmd/nm/nm_test.go
@@ -55,6 +55,10 @@
 }
 
 func TestNM(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	tmpDir, err := ioutil.TempDir("", "TestNM")
 	if err != nil {
 		t.Fatal("TempDir failed: ", err)
diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
index 6ad74c8..354e5d40 100644
--- a/src/cmd/objdump/objdump_test.go
+++ b/src/cmd/objdump/objdump_test.go
@@ -19,6 +19,10 @@
 )
 
 func loadSyms(t *testing.T) map[string]string {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	cmd := exec.Command("go", "tool", "nm", os.Args[0])
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -40,6 +44,10 @@
 }
 
 func runObjDump(t *testing.T, exe, startaddr, endaddr string) (path, lineno string) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	cmd := exec.Command(exe, os.Args[0], startaddr, endaddr)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -67,7 +75,7 @@
 	return f[0], f[1]
 }
 
-func testObjDump(t *testing.T, exe, startaddr, endaddr string) {
+func testObjDump(t *testing.T, exe, startaddr, endaddr string, line int) {
 	srcPath, srcLineNo := runObjDump(t, exe, startaddr, endaddr)
 	fi1, err := os.Stat("objdump_test.go")
 	if err != nil {
@@ -80,13 +88,13 @@
 	if !os.SameFile(fi1, fi2) {
 		t.Fatalf("objdump_test.go and %s are not same file", srcPath)
 	}
-	if srcLineNo != "89" {
-		t.Fatalf("line number = %v; want 89", srcLineNo)
+	if srcLineNo != fmt.Sprint(line) {
+		t.Fatalf("line number = %v; want %d", srcLineNo, line)
 	}
 }
 
-// This is line 88. The test depends on that.
 func TestObjDump(t *testing.T) {
+	_, _, line, _ := runtime.Caller(0)
 	syms := loadSyms(t)
 
 	tmp, exe := buildObjdump(t)
@@ -98,11 +106,15 @@
 		t.Fatalf("invalid start address %v: %v", startaddr, err)
 	}
 	endaddr := fmt.Sprintf("%x", addr+10)
-	testObjDump(t, exe, startaddr, endaddr)
-	testObjDump(t, exe, "0x"+startaddr, "0x"+endaddr)
+	testObjDump(t, exe, startaddr, endaddr, line-1)
+	testObjDump(t, exe, "0x"+startaddr, "0x"+endaddr, line-1)
 }
 
 func buildObjdump(t *testing.T) (tmp, exe string) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	tmp, err := ioutil.TempDir("", "TestObjDump")
 	if err != nil {
 		t.Fatal("TempDir failed: ", err)
diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go
index e634c86..4862426 100644
--- a/src/cmd/pack/pack_test.go
+++ b/src/cmd/pack/pack_test.go
@@ -14,6 +14,7 @@
 	"os/exec"
 	"path/filepath"
 	"regexp"
+	"runtime"
 	"testing"
 	"time"
 	"unicode/utf8"
@@ -185,6 +186,10 @@
 
 // Test that pack-created archives can be understood by the tools.
 func TestHello(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	dir := tmpDir(t)
 	defer os.RemoveAll(dir)
 	hello := filepath.Join(dir, "hello.go")
@@ -217,6 +222,10 @@
 
 // Test that pack works with very long lines in PKGDEF.
 func TestLargeDefs(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	dir := tmpDir(t)
 	defer os.RemoveAll(dir)
 	large := filepath.Join(dir, "large.go")
diff --git a/src/make.bash b/src/make.bash
index 0b130b6..d7b63ff 100755
--- a/src/make.bash
+++ b/src/make.bash
@@ -153,6 +153,7 @@
 buildall="-a"
 if [ "$1" = "--no-clean" ]; then
 	buildall=""
+	shift
 fi
 ./cmd/dist/dist bootstrap $buildall $GO_DISTFLAGS -v # builds go_bootstrap
 # Delay move of dist tool to now, because bootstrap may clear tool directory.
diff --git a/src/nacltest.bash b/src/nacltest.bash
new file mode 100644
index 0000000..e53f011
--- /dev/null
+++ b/src/nacltest.bash
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Copyright 2014 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.
+
+# For testing Native Client on builders or locally.
+# Builds a test file system and embeds it into package syscall
+# in every generated binary.
+#
+# Assumes that sel_ldr binaries are in $PATH; see ../misc/nacl/README.
+
+set -e
+ulimit -c 0
+
+# Check GOARCH.
+naclGOARCH=${GOARCH:-386}
+case "$naclGOARCH" in
+amd64p32)
+	if ! which sel_ldr_x86_64 >/dev/null; then
+		echo 'cannot find sel_ldr_x86_64' 1>&2
+		exit 1
+	fi
+	;;
+386)
+	if ! which sel_ldr_x86_32 >/dev/null; then
+		echo 'cannot find sel_ldr_x86_32' 1>&2
+		exit 1
+	fi
+	;;
+*)
+	echo 'unsupported $GOARCH for nacl: '"$naclGOARCH" 1>&2
+	exit 1
+esac
+
+# Run host build to get toolchain for running zip generator.
+unset GOOS GOARCH
+if [ ! -f make.bash ]; then
+	echo 'nacl.bash must be run from $GOROOT/src' 1>&2
+	exit 1
+fi
+GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH ./make.bash
+
+# Build zip file embedded in package syscall.
+gobin=${GOBIN:-$(pwd)/../bin}
+rm -f pkg/syscall/fstest_nacl.go
+GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH $gobin/go run ../misc/nacl/mkzip.go -p syscall -r .. ../misc/nacl/testzip.proto pkg/syscall/fstest_nacl.go
+
+# Run standard build and tests.
+export PATH=$(pwd)/../misc/nacl:$PATH
+GOOS=nacl GOARCH=$naclGOARCH ./all.bash --no-clean
diff --git a/src/pkg/crypto/x509/x509_test.go b/src/pkg/crypto/x509/x509_test.go
index ce9062c..2fd54c7 100644
--- a/src/pkg/crypto/x509/x509_test.go
+++ b/src/pkg/crypto/x509/x509_test.go
@@ -22,6 +22,7 @@
 	"net"
 	"os/exec"
 	"reflect"
+	"runtime"
 	"testing"
 	"time"
 )
@@ -727,6 +728,10 @@
 }
 
 func TestImports(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	if err := exec.Command("go", "run", "x509_test_import.go").Run(); err != nil {
 		t.Errorf("failed to run x509_test_import.go: %s", err)
 	}
diff --git a/src/pkg/net/http/cgi/matryoshka_test.go b/src/pkg/net/http/cgi/matryoshka_test.go
index 94f6467..18c4803 100644
--- a/src/pkg/net/http/cgi/matryoshka_test.go
+++ b/src/pkg/net/http/cgi/matryoshka_test.go
@@ -16,6 +16,7 @@
 	"net/http"
 	"net/http/httptest"
 	"os"
+	"runtime"
 	"testing"
 	"time"
 )
@@ -23,6 +24,10 @@
 // This test is a CGI host (testing host.go) that runs its own binary
 // as a child process testing the other half of CGI (child.go).
 func TestHostingOurselves(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	h := &Handler{
 		Path: os.Args[0],
 		Root: "/test.go",
@@ -87,6 +92,10 @@
 // If there's an error copying the child's output to the parent, test
 // that we kill the child.
 func TestKillChildAfterCopyError(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	defer func() { testHookStartProcess = nil }()
 	proc := make(chan *os.Process, 1)
 	testHookStartProcess = func(p *os.Process) {
@@ -130,6 +139,10 @@
 // Test that a child handler writing only headers works.
 // golang.org/issue/7196
 func TestChildOnlyHeaders(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	h := &Handler{
 		Path: os.Args[0],
 		Root: "/test.go",
diff --git a/src/pkg/net/packetconn_test.go b/src/pkg/net/packetconn_test.go
index 51f94ac..b6e4e76 100644
--- a/src/pkg/net/packetconn_test.go
+++ b/src/pkg/net/packetconn_test.go
@@ -40,7 +40,7 @@
 		return b, nil
 	case "unixgram":
 		switch runtime.GOOS {
-		case "plan9", "windows":
+		case "nacl", "plan9", "windows":
 			return nil, func() {
 				t.Logf("skipping %q test on %q", net, runtime.GOOS)
 			}
diff --git a/src/pkg/net/protoconn_test.go b/src/pkg/net/protoconn_test.go
index 47ae0ef..12856b6 100644
--- a/src/pkg/net/protoconn_test.go
+++ b/src/pkg/net/protoconn_test.go
@@ -236,7 +236,7 @@
 
 func TestUnixListenerSpecificMethods(t *testing.T) {
 	switch runtime.GOOS {
-	case "plan9", "windows":
+	case "nacl", "plan9", "windows":
 		t.Skipf("skipping test on %q", runtime.GOOS)
 	}
 
@@ -278,7 +278,7 @@
 
 func TestUnixConnSpecificMethods(t *testing.T) {
 	switch runtime.GOOS {
-	case "plan9", "windows":
+	case "nacl", "plan9", "windows":
 		t.Skipf("skipping test on %q", runtime.GOOS)
 	}
 
diff --git a/src/pkg/net/server_test.go b/src/pkg/net/server_test.go
index 86ebfb3..6a2bb92 100644
--- a/src/pkg/net/server_test.go
+++ b/src/pkg/net/server_test.go
@@ -16,7 +16,7 @@
 func skipServerTest(net, unixsotype, addr string, ipv6, ipv4map, linuxOnly bool) bool {
 	switch runtime.GOOS {
 	case "linux":
-	case "plan9", "windows":
+	case "nacl", "plan9", "windows":
 		// "unix" sockets are not supported on Windows and Plan 9.
 		if net == unixsotype {
 			return true
diff --git a/src/pkg/net/timeout_test.go b/src/pkg/net/timeout_test.go
index 2c56947..9ef0c4d 100644
--- a/src/pkg/net/timeout_test.go
+++ b/src/pkg/net/timeout_test.go
@@ -120,6 +120,9 @@
 			t.Fatalf("Read: expected err %v, got %v", errClosing, err)
 		}
 	default:
+		if err == io.EOF && runtime.GOOS == "nacl" { // close enough; golang.org/issue/8044
+			break
+		}
 		if err != errClosing {
 			t.Fatalf("Read: expected err %v, got %v", errClosing, err)
 		}
@@ -708,7 +711,7 @@
 
 func TestDeadlineRace(t *testing.T) {
 	switch runtime.GOOS {
-	case "plan9":
+	case "nacl", "plan9":
 		t.Skipf("skipping test on %q", runtime.GOOS)
 	}
 
diff --git a/src/pkg/net/unix_test.go b/src/pkg/net/unix_test.go
index 24b6bf9..05643dd 100644
--- a/src/pkg/net/unix_test.go
+++ b/src/pkg/net/unix_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !plan9,!windows
+// +build !nacl,!plan9,!windows
 
 package net
 
diff --git a/src/pkg/os/exec/exec_test.go b/src/pkg/os/exec/exec_test.go
index 7a95579..6f77ac3 100644
--- a/src/pkg/os/exec/exec_test.go
+++ b/src/pkg/os/exec/exec_test.go
@@ -27,7 +27,10 @@
 	"time"
 )
 
-func helperCommand(s ...string) *exec.Cmd {
+func helperCommand(t *testing.T, s ...string) *exec.Cmd {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
 	cs := []string{"-test.run=TestHelperProcess", "--"}
 	cs = append(cs, s...)
 	cmd := exec.Command(os.Args[0], cs...)
@@ -36,7 +39,7 @@
 }
 
 func TestEcho(t *testing.T) {
-	bs, err := helperCommand("echo", "foo bar", "baz").Output()
+	bs, err := helperCommand(t, "echo", "foo bar", "baz").Output()
 	if err != nil {
 		t.Errorf("echo: %v", err)
 	}
@@ -75,7 +78,7 @@
 func TestCatStdin(t *testing.T) {
 	// Cat, testing stdin and stdout.
 	input := "Input string\nLine 2"
-	p := helperCommand("cat")
+	p := helperCommand(t, "cat")
 	p.Stdin = strings.NewReader(input)
 	bs, err := p.Output()
 	if err != nil {
@@ -89,7 +92,7 @@
 
 func TestCatGoodAndBadFile(t *testing.T) {
 	// Testing combined output and error values.
-	bs, err := helperCommand("cat", "/bogus/file.foo", "exec_test.go").CombinedOutput()
+	bs, err := helperCommand(t, "cat", "/bogus/file.foo", "exec_test.go").CombinedOutput()
 	if _, ok := err.(*exec.ExitError); !ok {
 		t.Errorf("expected *exec.ExitError from cat combined; got %T: %v", err, err)
 	}
@@ -117,7 +120,7 @@
 
 func TestExitStatus(t *testing.T) {
 	// Test that exit values are returned correctly
-	cmd := helperCommand("exit", "42")
+	cmd := helperCommand(t, "exit", "42")
 	err := cmd.Run()
 	want := "exit status 42"
 	switch runtime.GOOS {
@@ -140,7 +143,7 @@
 		}
 	}
 	// Cat, testing stdin and stdout.
-	c := helperCommand("pipetest")
+	c := helperCommand(t, "pipetest")
 	stdin, err := c.StdinPipe()
 	check("StdinPipe", err)
 	stdout, err := c.StdoutPipe()
@@ -193,7 +196,7 @@
 			t.Fatalf("%s: %v", what, err)
 		}
 	}
-	cmd := helperCommand("stdinClose")
+	cmd := helperCommand(t, "stdinClose")
 	stdin, err := cmd.StdinPipe()
 	check("StdinPipe", err)
 	// Check that we can access methods of the underlying os.File.`
@@ -313,7 +316,7 @@
 	// Moving this test case around within the overall tests may
 	// affect the FDs obtained and hence the checks to catch these cases.
 	npipes := 2
-	c := helperCommand("extraFilesAndPipes", strconv.Itoa(npipes+1))
+	c := helperCommand(t, "extraFilesAndPipes", strconv.Itoa(npipes+1))
 	rd, wr, _ := os.Pipe()
 	defer rd.Close()
 	if rd.Fd() != 3 {
@@ -440,7 +443,7 @@
 		t.Fatalf("Seek: %v", err)
 	}
 
-	c := helperCommand("read3")
+	c := helperCommand(t, "read3")
 	var stdout, stderr bytes.Buffer
 	c.Stdout = &stdout
 	c.Stderr = &stderr
@@ -483,10 +486,10 @@
 
 	for i := 0; i < 10; i++ {
 		la := listen()
-		ca := helperCommand("describefiles")
+		ca := helperCommand(t, "describefiles")
 		ca.ExtraFiles = []*os.File{listenerFile(la)}
 		lb := listen()
-		cb := helperCommand("describefiles")
+		cb := helperCommand(t, "describefiles")
 		cb.ExtraFiles = []*os.File{listenerFile(lb)}
 		ares := make(chan string)
 		bres := make(chan string)
diff --git a/src/pkg/os/os_test.go b/src/pkg/os/os_test.go
index 6c2caa9..16d5984 100644
--- a/src/pkg/os/os_test.go
+++ b/src/pkg/os/os_test.go
@@ -496,10 +496,10 @@
 	}
 }
 
-func TestSymLink(t *testing.T) {
-	// Symlinks are not supported under windows or Plan 9.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return
+func TestSymlink(t *testing.T) {
+	switch runtime.GOOS {
+	case "windows", "plan9", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 	from, to := "symlinktestfrom", "symlinktestto"
 	Remove(from) // Just in case.
@@ -559,9 +559,9 @@
 }
 
 func TestLongSymlink(t *testing.T) {
-	// Symlinks are not supported under windows or Plan 9.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return
+	switch runtime.GOOS {
+	case "windows", "plan9", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 	s := "0123456789abcdef"
 	// Long, but not too long: a common limit is 255.
@@ -630,6 +630,10 @@
 }
 
 func TestStartProcess(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	var dir, cmd string
 	var args []string
 	if runtime.GOOS == "windows" {
@@ -703,8 +707,10 @@
 	checkSize(t, f, 1024)
 	f.Truncate(0)
 	checkSize(t, f, 0)
-	f.Write([]byte("surprise!"))
-	checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
+	_, err := f.Write([]byte("surprise!"))
+	if err == nil {
+		checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
+	}
 }
 
 func TestTruncate(t *testing.T) {
@@ -721,8 +727,10 @@
 	checkSize(t, f, 1024)
 	Truncate(f.Name(), 0)
 	checkSize(t, f, 0)
-	f.Write([]byte("surprise!"))
-	checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
+	_, err := f.Write([]byte("surprise!"))
+	if err == nil {
+		checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
+	}
 }
 
 // Use TempDir() to make sure we're on a local file system,
@@ -757,13 +765,13 @@
 	}
 	postStat := st
 
-	/* Plan 9:
+	/* Plan 9, NaCl:
 		Mtime is the time of the last change of content.  Similarly, atime is set whenever the
 	    contents are accessed; also, it is set whenever mtime is set.
 	*/
 	pat := Atime(postStat)
 	pmt := postStat.ModTime()
-	if !pat.Before(at) && runtime.GOOS != "plan9" {
+	if !pat.Before(at) && runtime.GOOS != "plan9" && runtime.GOOS != "nacl" {
 		t.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at, pat)
 	}
 
@@ -965,8 +973,9 @@
 func TestHostname(t *testing.T) {
 	// There is no other way to fetch hostname on windows, but via winapi.
 	// On Plan 9 it is can be taken from #c/sysname as Hostname() does.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return
+	switch runtime.GOOS {
+	case "windows", "plan9", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 
 	// Check internal Hostname() against the output of /bin/hostname.
@@ -1225,6 +1234,10 @@
 }
 
 func testKillProcess(t *testing.T, processKiller func(p *Process)) {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	dir, err := ioutil.TempDir("", "go-build")
 	if err != nil {
 		t.Fatalf("Failed to create temp directory: %v", err)
diff --git a/src/pkg/os/path_test.go b/src/pkg/os/path_test.go
index 27abf59..3af21cd 100644
--- a/src/pkg/os/path_test.go
+++ b/src/pkg/os/path_test.go
@@ -167,8 +167,9 @@
 }
 
 func TestMkdirAllWithSymlink(t *testing.T) {
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		t.Skip("Skipping test: symlinks don't exist under Windows/Plan 9")
+	switch runtime.GOOS {
+	case "nacl", "plan9", "windows":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 
 	tmpDir, err := ioutil.TempDir("", "TestMkdirAllWithSymlink-")
diff --git a/src/pkg/path/filepath/match_test.go b/src/pkg/path/filepath/match_test.go
index daec815..382692e 100644
--- a/src/pkg/path/filepath/match_test.go
+++ b/src/pkg/path/filepath/match_test.go
@@ -167,11 +167,10 @@
 
 func TestGlobSymlink(t *testing.T) {
 	switch runtime.GOOS {
-	case "windows", "plan9":
-		// The tests below are Unix specific so we skip plan9, which does not
-		// support symlinks, and windows.
-		t.Skipf("skipping test on %v", runtime.GOOS)
+	case "nacl", "plan9", "windows":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
+
 	tmpDir, err := ioutil.TempDir("", "globsymlink")
 	if err != nil {
 		t.Fatal("creating temp dir:", err)
diff --git a/src/pkg/path/filepath/path_test.go b/src/pkg/path/filepath/path_test.go
index 1adc8cb..819bd21 100644
--- a/src/pkg/path/filepath/path_test.go
+++ b/src/pkg/path/filepath/path_test.go
@@ -691,8 +691,9 @@
 }
 
 func TestEvalSymlinks(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("Skipping test: symlinks don't exist under Plan 9")
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 
 	tmpDir, err := ioutil.TempDir("", "evalsymlink")
diff --git a/src/pkg/runtime/asm_amd64p32.s b/src/pkg/runtime/asm_amd64p32.s
index 775ffcc..d47f122 100644
--- a/src/pkg/runtime/asm_amd64p32.s
+++ b/src/pkg/runtime/asm_amd64p32.s
@@ -302,7 +302,7 @@
 	JMP	AX
 
 #define CALLFN(NAME,MAXSIZE)			\
-TEXT runtime·NAME(SB), WRAPPER, $MAXSIZE-12;		\
+TEXT runtime·NAME(SB), WRAPPER, $MAXSIZE-16;		\
 	/* copy arguments to stack */		\
 	MOVL	argptr+4(FP), SI;		\
 	MOVL	argsize+8(FP), CX;		\
@@ -315,7 +315,11 @@
 	/* copy return values back */		\
 	MOVL	argptr+4(FP), DI;		\
 	MOVL	argsize+8(FP), CX;		\
+	MOVL	retoffset+12(FP), BX;		\
 	MOVL	SP, SI;				\
+	ADDL	BX, DI;				\
+	ADDL	BX, SI;				\
+	SUBL	BX, CX;				\
 	REP;MOVSB;				\
 	RET
 
diff --git a/src/pkg/runtime/crash_test.go b/src/pkg/runtime/crash_test.go
index dbcd948..b2e846a 100644
--- a/src/pkg/runtime/crash_test.go
+++ b/src/pkg/runtime/crash_test.go
@@ -9,6 +9,7 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"runtime"
 	"strings"
 	"testing"
 	"text/template"
@@ -31,6 +32,10 @@
 }
 
 func executeTest(t *testing.T, templ string, data interface{}) string {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	checkStaleRuntime(t)
 
 	st := template.Must(template.New("crashSource").Parse(templ))
diff --git a/src/pkg/runtime/pprof/pprof_test.go b/src/pkg/runtime/pprof/pprof_test.go
index 91f5300..aba538e 100644
--- a/src/pkg/runtime/pprof/pprof_test.go
+++ b/src/pkg/runtime/pprof/pprof_test.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// +build !nacl
+
 package pprof_test
 
 import (
diff --git a/src/pkg/runtime/runtime_test.go b/src/pkg/runtime/runtime_test.go
index 62e59c7..5a9f52f 100644
--- a/src/pkg/runtime/runtime_test.go
+++ b/src/pkg/runtime/runtime_test.go
@@ -95,6 +95,10 @@
 // The value reported will include the padding between runtime.gogo and the
 // next function in memory. That's fine.
 func TestRuntimeGogoBytes(t *testing.T) {
+	if GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+
 	dir, err := ioutil.TempDir("", "go-build")
 	if err != nil {
 		t.Fatalf("failed to create temp directory: %v", err)
@@ -183,6 +187,10 @@
 }
 
 func testSetPanicOnFault(t *testing.T, addr uintptr) {
+	if GOOS == "nacl" {
+		t.Skip("nacl doesn't seem to fault on high addresses")
+	}
+
 	defer func() {
 		if err := recover(); err == nil {
 			t.Fatalf("did not find error in recover")
diff --git a/src/run.bash b/src/run.bash
index 876b5d7..4706c2b 100755
--- a/src/run.bash
+++ b/src/run.bash
@@ -34,7 +34,7 @@
 
 # allow all.bash to avoid double-build of everything
 rebuild=true
-if [ "$1" = "--no-rebuild" ]; then
+if [ "$1" == "--no-rebuild" ]; then
 	shift
 else
 	echo '# Building packages and commands.'
@@ -178,15 +178,18 @@
 ./test.bash || exit 1
 ) || exit $?
 
+[ "$GOOS" == nacl ] ||
 (xcd ../doc/progs
 time ./run || exit 1
 ) || exit $?
 
+[ "$GOOS" == nacl ] ||
 [ "$GOARCH" == arm ] ||  # uses network, fails under QEMU
 (xcd ../doc/articles/wiki
 ./test.bash || exit 1
 ) || exit $?
 
+[ "$GOOS" == nacl ] ||
 (xcd ../doc/codewalk
 time ./run || exit 1
 ) || exit $?
@@ -196,6 +199,7 @@
 go build ../misc/goplay
 rm -f goplay
 
+[ "$GOOS" == nacl ] ||
 [ "$GOARCH" == arm ] ||
 (xcd ../test/bench/shootout
 time ./timing.sh -test || exit 1
@@ -210,12 +214,17 @@
 
 (xcd ../test
 unset GOMAXPROCS
-time go run run.go || exit 1
+GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH go build -o runtest run.go || exit 1
+time ./runtest || exit 1
+rm -f runtest
 ) || exit $?
 
+[ "$GOOS" == nacl ] ||
+(
 echo
 echo '# Checking API compatibility.'
-time go run $GOROOT/src/cmd/api/run.go
+time go run $GOROOT/src/cmd/api/run.go || exit 1
+) || exit $?
 
 echo
 echo ALL TESTS PASSED