diff --git a/cmd/toolstash/LICENSE b/cmd/toolstash/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/cmd/toolstash/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/cmd/toolstash/README.md b/cmd/toolstash/README.md
new file mode 100644
index 0000000..7d71c8b
--- /dev/null
+++ b/cmd/toolstash/README.md
@@ -0,0 +1,3 @@
+go get rsc.io/toolstash
+
+http://godoc.org/rsc.io/toolstash
diff --git a/cmd/toolstash/buildall b/cmd/toolstash/buildall
new file mode 100755
index 0000000..65c6846
--- /dev/null
+++ b/cmd/toolstash/buildall
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+# Usage: buildall [-e] [-nocmp] [-work]
+#
+# Builds everything (std) for every GOOS/GOARCH combination but installs nothing.
+#
+# By default, runs the builds with -toolexec 'toolstash -cmp', to test that the
+# toolchain is producing bit identical output to a previous known good toolchain.
+#
+# Options:
+#	-e: stop at first failure
+#	-nocmp: turn off toolstash -cmp; just check that ordinary builds succeed
+#	-work: pass -work to go command
+
+sete=false
+if [ "$1" = "-e" ]; then
+	sete=true
+	shift
+fi
+
+cmp=true
+if [ "$1" = "-nocmp" ]; then
+	cmp=false
+	shift
+fi
+
+work=""
+if [ "$1" = "-work" ]; then
+	work="-work"
+	shift
+fi
+
+cd $(go env GOROOT)/src
+go install cmd/compile cmd/link cmd/asm || exit 1
+pattern="$1"
+if [ "$pattern" = "" ]; then
+	pattern=.
+fi
+
+# put linux, nacl first in the target list to get all the architectures up front.
+targets="$((ls runtime | 9 sed -n 's/^rt0_(.*)_(.*)\.s/\1-\2/p'; echo linux-386-387) | sort | egrep -v android-arm | egrep "$pattern" | egrep 'linux|nacl')
+	$(ls runtime | 9 sed -n 's/^rt0_(.*)_(.*)\.s/\1-\2/p' | egrep -v 'android-arm|darwin-arm' | egrep "$pattern" | egrep -v 'linux|nacl')"
+if [ "$sete" = true ]; then
+	set -e
+fi
+for target in $targets
+do
+	echo $target
+	export GOOS=$(echo $target | sed 's/-.*//')
+	export GOARCH=$(echo $target | sed 's/.*-//')
+	unset GO386
+	if [ "$GOARCH" = "387" ]; then
+		export GOARCH=386
+		export GO386=387
+	fi
+	if $cmp; then
+		go build $work -a -toolexec 'toolstash -cmp' std cmd
+	else
+		go build $work -a std
+	fi
+done
diff --git a/cmd/toolstash/cmp.go b/cmd/toolstash/cmp.go
new file mode 100644
index 0000000..f5974e1
--- /dev/null
+++ b/cmd/toolstash/cmp.go
@@ -0,0 +1,157 @@
+// Copyright 2015 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+var (
+	hexDumpRE = regexp.MustCompile(`^\t(0x[0-9a-f]{4,})(( ([0-9a-f]{2}|  )){16})  [ -\x7F]{1,16}\n`)
+	listingRE = regexp.MustCompile(`^\t(0x[0-9a-f]{4,}) ([0-9]{4,}) \(.*:[0-9]+\)\t`)
+)
+
+// okdiffs lists regular expressions for lines to consider minor mismatches.
+// If one of these regexps matches both of a pair of unequal lines, the mismatch
+// is reported but not treated as the one worth looking for.
+// For example, differences in the TEXT line are typically frame size
+// changes due to optimization decisions made in the body of the function.
+// Better to keep looking for the actual difference.
+// Similarly, forward jumps might have different offsets due to a
+// change in instruction encoding later on.
+// Better to find that change.
+var okdiffs = []*regexp.Regexp{
+	regexp.MustCompile(`\)	TEXT[ 	].*,\$`),
+	regexp.MustCompile(`\)	WORD[ 	].*,\$`),
+	regexp.MustCompile(`\)	(B|BR|JMP)	`),
+	regexp.MustCompile(`\)	FUNCDATA	`),
+	regexp.MustCompile(`\\(z|x00)`),
+	regexp.MustCompile(`\$\([0-9]\.[0-9]+e[+\-][0-9]+\)`),
+	regexp.MustCompile(`size=.*value=.*args=.*locals=`),
+}
+
+func compareLogs(outfile string) string {
+	f1, err := os.Open(outfile + ".log")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer f1.Close()
+
+	f2, err := os.Open(outfile + ".stash.log")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer f2.Close()
+
+	b1 := bufio.NewReader(f1)
+	b2 := bufio.NewReader(f2)
+
+	offset := int64(0)
+	textOffset := offset
+	textLineno := 0
+	lineno := 0
+	var line1, line2 string
+	var prefix bytes.Buffer
+Reading:
+	for {
+		var err1, err2 error
+		line1, err1 = b1.ReadString('\n')
+		line2, err2 = b2.ReadString('\n')
+		if strings.Contains(line1, ")\tTEXT\t") {
+			textOffset = offset
+			textLineno = lineno
+		}
+		offset += int64(len(line1))
+		lineno++
+		if err1 == io.EOF && err2 == io.EOF {
+			return "no differences in debugging output"
+		}
+
+		if lineno == 1 || line1 == line2 && err1 == nil && err2 == nil {
+			continue
+		}
+		// Lines are inconsistent. Worth stopping?
+		for _, re := range okdiffs {
+			if re.MatchString(line1) && re.MatchString(line2) {
+				fmt.Fprintf(&prefix, "inconsistent log line:\n%s:%d:\n\t%s\n%s:%d:\n\t%s\n\n",
+					f1.Name(), lineno, strings.TrimSuffix(line1, "\n"),
+					f2.Name(), lineno, strings.TrimSuffix(line2, "\n"))
+				continue Reading
+			}
+		}
+
+		if err1 != nil {
+			line1 = err1.Error()
+		}
+		if err2 != nil {
+			line2 = err2.Error()
+		}
+		break
+	}
+
+	msg := fmt.Sprintf("inconsistent log line:\n%s:%d:\n\t%s\n%s:%d:\n\t%s",
+		f1.Name(), lineno, strings.TrimSuffix(line1, "\n"),
+		f2.Name(), lineno, strings.TrimSuffix(line2, "\n"))
+
+	if m := hexDumpRE.FindStringSubmatch(line1); m != nil {
+		target, err := strconv.ParseUint(m[1], 0, 64)
+		if err != nil {
+			goto Skip
+		}
+
+		m2 := hexDumpRE.FindStringSubmatch(line2)
+		if m2 == nil {
+			goto Skip
+		}
+
+		fields1 := strings.Fields(m[2])
+		fields2 := strings.Fields(m2[2])
+		i := 0
+		for i < len(fields1) && i < len(fields2) && fields1[i] == fields2[i] {
+			i++
+		}
+		target += uint64(i)
+
+		f1.Seek(textOffset, 0)
+		b1 = bufio.NewReader(f1)
+		last := ""
+		lineno := textLineno
+		limitAddr := uint64(0)
+		lastAddr := uint64(0)
+		for {
+			line1, err1 := b1.ReadString('\n')
+			if err1 != nil {
+				break
+			}
+			lineno++
+			if m := listingRE.FindStringSubmatch(line1); m != nil {
+				addr, _ := strconv.ParseUint(m[1], 0, 64)
+				if addr > target {
+					limitAddr = addr
+					break
+				}
+				last = line1
+				lastAddr = addr
+			} else if hexDumpRE.FindStringSubmatch(line1) != nil {
+				break
+			}
+		}
+		if last != "" {
+			msg = fmt.Sprintf("assembly instruction at %#04x-%#04x:\n%s:%d\n\t%s\n\n%s",
+				lastAddr, limitAddr, f1.Name(), lineno-1, strings.TrimSuffix(last, "\n"), msg)
+		}
+	}
+Skip:
+
+	return prefix.String() + msg
+}
diff --git a/cmd/toolstash/main.go b/cmd/toolstash/main.go
new file mode 100644
index 0000000..2004cd7
--- /dev/null
+++ b/cmd/toolstash/main.go
@@ -0,0 +1,600 @@
+// Copyright 2015 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.
+
+// Toolstash provides a way to save, run, and restore a known good copy of the Go toolchain
+// and to compare the object files generated by two toolchains.
+//
+// Usage:
+//
+//	toolstash [-n] [-v] save [tool...]
+//	toolstash [-n] [-v] restore [tool...]
+//	toolstash [-n] [-v] [-t] go run x.go
+//	toolstash [-n] [-v] [-t] [-cmp] compile x.go
+//
+// The toolstash command manages a ``stashed'' copy of the Go toolchain
+// kept in $GOROOT/pkg/toolstash. In this case, the toolchain means the
+// tools available with the 'go tool' command as well as the go, godoc, and gofmt
+// binaries.
+//
+// The command ``toolstash save'', typically run when the toolchain is known to be working,
+// copies the toolchain from its installed location to the toolstash directory.
+// Its inverse, ``toolchain restore'', typically run when the toolchain is known to be broken,
+// copies the toolchain from the toolstash directory back to the installed locations.
+// If additional arguments are given, the save or restore applies only to the named tools.
+// Otherwise, it applies to all tools.
+//
+// Otherwise, toolstash's arguments should be a command line beginning with the
+// name of a toolchain binary, which may be a short name like compile or a complete path
+// to an installed binary. Toolstash runs the command line using the stashed
+// copy of the binary instead of the installed one.
+//
+// The -n flag causes toolstash to print the commands that would be executed
+// but not execute them. The combination -n -cmp shows the two commands
+// that would be compared and then exits successfully. A real -cmp run might
+// run additional commands for diagnosis of an output mismatch.
+//
+// The -v flag causes toolstash to print the commands being executed.
+//
+// The -t flag causes toolstash to print the time elapsed during while the
+// command ran.
+//
+// Comparing
+//
+// The -cmp flag causes toolstash to run both the installed and the stashed
+// copy of an assembler or compiler and check that they produce identical
+// object files. If not, toolstash reports the mismatch and exits with a failure status.
+// As part of reporting the mismatch, toolstash reinvokes the command with
+// the -S flag and identifies the first divergence in the assembly output.
+// If the command is a Go compiler, toolstash also determines whether the
+// difference is triggered by optimization passes.
+// On failure, toolstash leaves additional information in files named
+// similarly to the default output file. If the compilation would normally
+// produce a file x.6, the output from the stashed tool is left in x.6.stash
+// and the debugging traces are left in x.6.log and x.6.stash.log.
+//
+// The -cmp flag is a no-op when the command line is not invoking an
+// assembler or compiler.
+//
+// For example, when working on code cleanup that should not affect
+// compiler output, toolstash can be used to compare the old and new
+// compiler output:
+//
+//	toolstash save
+//	<edit compiler sources>
+//	go tool dist install cmd/compile # install compiler only
+//	toolstash -cmp compile x.go
+//
+// Go Command Integration
+//
+// The go command accepts a -toolexec flag that specifies a program
+// to use to run the build tools.
+//
+// To build with the stashed tools:
+//
+//	go build -toolexec toolstash x.go
+//
+// To build with the stashed go command and the stashed tools:
+//
+//	toolstash go build -toolexec toolstash x.go
+//
+// To verify that code cleanup in the compilers does not make any
+// changes to the objects being generated for the entire tree:
+//
+//	# Build working tree and save tools.
+//	./make.bash
+//	toolstash save
+//
+//	<edit compiler sources>
+//
+//	# Install new tools, but do not rebuild the rest of tree,
+//	# since the compilers might generate buggy code.
+//	go tool dist install cmd/compile
+//
+//	# Check that new tools behave identically to saved tools.
+//	go build -toolexec 'toolstash -cmp' -a std
+//
+//	# If not, restore, in order to keep working on Go code.
+//	toolstash restore
+//
+// Version Skew
+//
+// The Go tools write the current Go version to object files, and (outside
+// release branches) that version includes the hash and time stamp
+// of the most recent Git commit. Functionally equivalent
+// compilers built at different Git versions may produce object files that
+// differ only in the recorded version. Toolstash ignores version mismatches
+// when comparing object files, but the standard tools will refuse to compile
+// or link together packages with different object versions.
+//
+// For the full build in the final example above to work, both the stashed
+// and the installed tools must use the same version string.
+// One way to ensure this is not to commit any of the changes being
+// tested, so that the Git HEAD hash is the same for both builds.
+// A more robust way to force the tools to have the same version string
+// is to write a $GOROOT/VERSION file, which overrides the Git-based version
+// computation:
+//
+//	echo devel >$GOROOT/VERSION
+//
+// The version can be arbitrary text, but to pass all.bash's API check, it must
+// contain the substring ``devel''. The VERSION file must be created before
+// building either version of the toolchain.
+//
+package main // import "rsc.io/toolstash"
+
+import (
+	"bufio"
+	"flag"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"time"
+)
+
+var usageMessage = `usage: toolstash [-n] [-v] [-cmp] command line
+
+Examples:
+	toolstash save
+	toolstash restore
+	toolstash go run x.go
+	toolstash compile x.go
+	toolstash -cmp compile x.go
+
+For details, godoc rsc.io/toolstash
+`
+
+func usage() {
+	fmt.Fprint(os.Stderr, usageMessage)
+	os.Exit(2)
+}
+
+var (
+	norun   = flag.Bool("n", false, "print but do not run commands")
+	verbose = flag.Bool("v", false, "print commands being run")
+	cmp     = flag.Bool("cmp", false, "compare tool object files")
+	timing  = flag.Bool("t", false, "print time commands take")
+)
+
+var (
+	cmd       []string
+	tool      string // name of tool: "go", "compile", etc
+	toolStash string // path to stashed tool
+
+	goroot   string
+	toolDir  string
+	stashDir string
+	binDir   string
+)
+
+func canCmp(name string) bool {
+	switch name {
+	case "compile", "link", "asm":
+		return true
+	}
+	return len(name) == 2 && '0' <= name[0] && name[0] <= '9' && (name[1] == 'a' || name[1] == 'g' || name[1] == 'l')
+}
+
+var binTools = []string{"go", "godoc", "gofmt"}
+
+func isBinTool(name string) bool {
+	return strings.HasPrefix(name, "go")
+}
+
+func main() {
+	log.SetFlags(0)
+	log.SetPrefix("toolstash: ")
+
+	flag.Usage = usage
+	flag.Parse()
+	cmd = flag.Args()
+
+	if len(cmd) < 1 {
+		usage()
+	}
+
+	goroot = runtime.GOROOT()
+	toolDir = filepath.Join(goroot, fmt.Sprintf("pkg/tool/%s_%s", runtime.GOOS, runtime.GOARCH))
+	stashDir = filepath.Join(goroot, "pkg/toolstash")
+
+	binDir = os.Getenv("GOBIN")
+	if binDir == "" {
+		binDir = filepath.Join(goroot, "bin")
+	}
+
+	switch cmd[0] {
+	case "save":
+		save()
+		return
+
+	case "restore":
+		restore()
+		return
+	}
+
+	tool = cmd[0]
+	if i := strings.LastIndex(tool, "/"); i >= 0 {
+		tool = tool[i+1:]
+	}
+	if i := strings.LastIndex(tool, `\`); i >= 0 {
+		tool = tool[i+1:]
+	}
+
+	if !strings.HasPrefix(tool, "a.out") {
+		toolStash = filepath.Join(stashDir, tool)
+		if _, err := os.Stat(toolStash); err != nil {
+			log.Print(err)
+			os.Exit(2)
+		}
+
+		if *cmp && canCmp(tool) {
+			compareTool()
+			return
+		}
+		cmd[0] = toolStash
+	}
+
+	if *norun {
+		fmt.Printf("%s\n", strings.Join(cmd, " "))
+		return
+	}
+	if *verbose {
+		log.Print(strings.Join(cmd, " "))
+	}
+	xcmd := exec.Command(cmd[0], cmd[1:]...)
+	xcmd.Stdin = os.Stdin
+	xcmd.Stdout = os.Stdout
+	xcmd.Stderr = os.Stderr
+	err := xcmd.Run()
+	if err != nil {
+		log.Fatal(err)
+	}
+	os.Exit(0)
+}
+
+func compareTool() {
+	if !strings.Contains(cmd[0], "/") && !strings.Contains(cmd[0], `\`) {
+		cmd[0] = filepath.Join(toolDir, tool)
+	}
+
+	outfile, ok := cmpRun(false, cmd)
+	if ok {
+		os.Remove(outfile + ".stash")
+		return
+	}
+
+	extra := "-S"
+	switch {
+	default:
+		log.Fatalf("unknown tool %s", tool)
+
+	case tool == "compile" || strings.HasSuffix(tool, "g"): // compiler
+		cmdN := append([]string{cmd[0], "-N"}, cmd[1:]...)
+		_, ok := cmpRun(false, cmdN)
+		if !ok {
+			log.Printf("compiler output differs, even with optimizers disabled (-N)")
+			cmd = append([]string{cmd[0], "-v", "-N", "-m=2"}, cmd[1:]...)
+			break
+		}
+		cmd = append([]string{cmd[0], "-v", "-m=2"}, cmd[1:]...)
+		log.Printf("compiler output differs, only with optimizers enabled")
+
+	case tool == "asm" || strings.HasSuffix(tool, "a"): // assembler
+		log.Printf("assembler output differs")
+
+	case tool == "link" || strings.HasSuffix(tool, "l"): // linker
+		log.Printf("linker output differs")
+		extra = "-v=2"
+	}
+
+	cmdS := append([]string{cmd[0], extra}, cmd[1:]...)
+	outfile, ok = cmpRun(true, cmdS)
+
+	fmt.Fprintf(os.Stderr, "\n%s\n", compareLogs(outfile))
+	os.Exit(2)
+}
+
+func cmpRun(keepLog bool, cmd []string) (outfile string, match bool) {
+	cmdStash := make([]string, len(cmd))
+	copy(cmdStash, cmd)
+	cmdStash[0] = toolStash
+	for i, arg := range cmdStash {
+		if arg == "-o" {
+			outfile = cmdStash[i+1]
+			cmdStash[i+1] += ".stash"
+			break
+		}
+		if strings.HasSuffix(arg, ".s") || strings.HasSuffix(arg, ".go") && '0' <= tool[0] && tool[0] <= '9' {
+			outfile = filepath.Base(arg[:strings.LastIndex(arg, ".")] + "." + tool[:1])
+			cmdStash = append([]string{cmdStash[0], "-o", outfile + ".stash"}, cmdStash[1:]...)
+			break
+		}
+	}
+
+	if outfile == "" {
+		log.Fatalf("cannot determine output file for command: %s", strings.Join(cmd, " "))
+	}
+
+	if *norun {
+		fmt.Printf("%s\n", strings.Join(cmd, " "))
+		fmt.Printf("%s\n", strings.Join(cmdStash, " "))
+		os.Exit(0)
+	}
+
+	out, err := runCmd(cmd, keepLog, outfile+".log")
+	if err != nil {
+		log.Printf("running: %s", strings.Join(cmd, " "))
+		os.Stderr.Write(out)
+		log.Fatal(err)
+	}
+
+	outStash, err := runCmd(cmdStash, keepLog, outfile+".stash.log")
+	if err != nil {
+		log.Printf("running: %s", strings.Join(cmdStash, " "))
+		log.Printf("installed tool succeeded but stashed tool failed.\n")
+		if len(out) > 0 {
+			log.Printf("installed tool output:")
+			os.Stderr.Write(out)
+		}
+		if len(outStash) > 0 {
+			log.Printf("stashed tool output:")
+			os.Stderr.Write(outStash)
+		}
+		log.Fatal(err)
+	}
+
+	return outfile, sameObject(outfile, outfile+".stash")
+}
+
+func sameObject(file1, file2 string) bool {
+	f1, err := os.Open(file1)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer f1.Close()
+
+	f2, err := os.Open(file2)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer f2.Close()
+
+	b1 := bufio.NewReader(f1)
+	b2 := bufio.NewReader(f2)
+
+	// Go object files and archives contain lines of the form
+	//	go object <goos> <goarch> <version>
+	// By default, the version on development branches includes
+	// the Git hash and time stamp for the most recent commit.
+	// We allow the versions to differ.
+	if !skipVersion(b1, b2, file1, file2) {
+		return false
+	}
+
+	lastByte := byte(0)
+	for {
+		c1, err1 := b1.ReadByte()
+		c2, err2 := b2.ReadByte()
+		if err1 == io.EOF && err2 == io.EOF {
+			return true
+		}
+		if err1 != nil {
+			log.Fatalf("reading %s: %v", file1, err1)
+		}
+		if err2 != nil {
+			log.Fatalf("reading %s: %v", file2, err1)
+		}
+		if c1 != c2 {
+			return false
+		}
+		if lastByte == '`' && c1 == '\n' {
+			if !skipVersion(b1, b2, file1, file2) {
+				return false
+			}
+		}
+		lastByte = c1
+	}
+}
+
+func skipVersion(b1, b2 *bufio.Reader, file1, file2 string) bool {
+	// Consume "go object " prefix, if there.
+	prefix := "go object "
+	for i := 0; i < len(prefix); i++ {
+		c1, err1 := b1.ReadByte()
+		c2, err2 := b2.ReadByte()
+		if err1 == io.EOF && err2 == io.EOF {
+			return true
+		}
+		if err1 != nil {
+			log.Fatalf("reading %s: %v", file1, err1)
+		}
+		if err2 != nil {
+			log.Fatalf("reading %s: %v", file2, err1)
+		}
+		if c1 != c2 {
+			return false
+		}
+		if c1 != prefix[i] {
+			return true // matching bytes, just not a version
+		}
+	}
+
+	// Keep comparing until second space.
+	// Must continue to match.
+	// If we see a \n, it's not a version string after all.
+	for numSpace := 0; numSpace < 2; {
+		c1, err1 := b1.ReadByte()
+		c2, err2 := b2.ReadByte()
+		if err1 == io.EOF && err2 == io.EOF {
+			return true
+		}
+		if err1 != nil {
+			log.Fatalf("reading %s: %v", file1, err1)
+		}
+		if err2 != nil {
+			log.Fatalf("reading %s: %v", file2, err1)
+		}
+		if c1 != c2 {
+			return false
+		}
+		if c1 == '\n' {
+			return true
+		}
+		if c1 == ' ' {
+			numSpace++
+		}
+	}
+
+	// Have now seen 'go object goos goarch ' in both files.
+	// Now they're allowed to diverge, until the \n, which
+	// must be present.
+	for {
+		c1, err1 := b1.ReadByte()
+		if err1 == io.EOF {
+			log.Fatalf("reading %s: unexpected EOF", file1, err1)
+		}
+		if err1 != nil {
+			log.Fatalf("reading %s: %v", file1, err1)
+		}
+		if c1 == '\n' {
+			break
+		}
+	}
+	for {
+		c2, err2 := b2.ReadByte()
+		if err2 == io.EOF {
+			log.Fatalf("reading %s: unexpected EOF", file2, err2)
+		}
+		if err2 != nil {
+			log.Fatalf("reading %s: %v", file2, err2)
+		}
+		if c2 == '\n' {
+			break
+		}
+	}
+
+	// Consumed "matching" versions from both.
+	return true
+}
+
+func runCmd(cmd []string, keepLog bool, logName string) (output []byte, err error) {
+	if *verbose {
+		log.Print(strings.Join(cmd, " "))
+	}
+
+	if *timing {
+		t0 := time.Now()
+		defer func() {
+			log.Printf("%.3fs elapsed # %s\n", time.Since(t0).Seconds(), strings.Join(cmd, " "))
+		}()
+	}
+
+	xcmd := exec.Command(cmd[0], cmd[1:]...)
+	if !keepLog {
+		return xcmd.CombinedOutput()
+	}
+
+	f, err := os.Create(logName)
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Fprintf(f, "GOOS=%s GOARCH=%s %s\n", os.Getenv("GOOS"), os.Getenv("GOARCH"), strings.Join(cmd, " "))
+	xcmd.Stdout = f
+	xcmd.Stderr = f
+	defer f.Close()
+	return nil, xcmd.Run()
+}
+
+func save() {
+	if err := os.MkdirAll(stashDir, 0777); err != nil {
+		log.Fatal(err)
+	}
+
+	toolDir := filepath.Join(goroot, fmt.Sprintf("pkg/tool/%s_%s", runtime.GOOS, runtime.GOARCH))
+	files, err := ioutil.ReadDir(toolDir)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	for _, file := range files {
+		if shouldSave(file.Name()) && file.Mode().IsRegular() {
+			cp(filepath.Join(toolDir, file.Name()), filepath.Join(stashDir, file.Name()))
+		}
+	}
+
+	for _, name := range binTools {
+		if !shouldSave(name) {
+			continue
+		}
+		src := filepath.Join(binDir, name)
+		if _, err := os.Stat(src); err == nil {
+			cp(src, filepath.Join(stashDir, name))
+		}
+	}
+
+	checkShouldSave()
+}
+
+func restore() {
+	files, err := ioutil.ReadDir(stashDir)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	for _, file := range files {
+		if shouldSave(file.Name()) && file.Mode().IsRegular() {
+			targ := toolDir
+			if isBinTool(file.Name()) {
+				targ = binDir
+			}
+			cp(filepath.Join(stashDir, file.Name()), filepath.Join(targ, file.Name()))
+		}
+	}
+
+	checkShouldSave()
+}
+
+func shouldSave(name string) bool {
+	if len(cmd) == 1 {
+		return true
+	}
+	ok := false
+	for i, arg := range cmd {
+		if i > 0 && name == arg {
+			ok = true
+			cmd[i] = "DONE"
+		}
+	}
+	return ok
+}
+
+func checkShouldSave() {
+	var missing []string
+	for _, arg := range cmd[1:] {
+		if arg != "DONE" {
+			missing = append(missing, arg)
+		}
+	}
+	if len(missing) > 0 {
+		log.Fatalf("%s did not find tools: %s", cmd[0], strings.Join(missing, " "))
+	}
+}
+
+func cp(src, dst string) {
+	if *verbose {
+		fmt.Printf("cp %s %s\n", src, dst)
+	}
+	data, err := ioutil.ReadFile(src)
+	if err != nil {
+		log.Fatal(err)
+	}
+	if err := ioutil.WriteFile(dst, data, 0777); err != nil {
+		log.Fatal(err)
+	}
+}
