[Pkg-golang-commits] [golang] 01/02: Imported Upstream version 1.5

Tianon Gravi tianon at debian.org
Wed Aug 19 22:08:25 UTC 2015


This is an automated email from the git hooks/post-receive script.

tianon pushed a commit to branch debian-sid
in repository golang.

commit a7f6064ed5697f1d12d638509bd1180520e73558
Author: Tianon Gravi <admwiggin at gmail.com>
Date:   Wed Aug 19 15:07:07 2015 -0700

    Imported Upstream version 1.5
---
 VERSION                                       |   2 +-
 doc/asm.html                                  |   4 +-
 doc/contrib.html                              |   1 +
 doc/devel/release.html                        |   7 ++
 doc/go1.5.html                                |  54 ++++++-------
 doc/install.html                              |  16 ++--
 src/cmd/compile/internal/amd64/ggen.go        |   8 +-
 src/cmd/compile/internal/amd64/reg.go         |   2 -
 src/cmd/compile/internal/arm64/ggen.go        |   9 +--
 src/cmd/compile/internal/arm64/reg.go         |   2 -
 src/cmd/compile/internal/gc/gsubr.go          |   7 ++
 src/cmd/compile/internal/gc/typecheck.go      |   2 +-
 src/cmd/compile/internal/gc/walk.go           |   2 +-
 src/cmd/compile/internal/ppc64/ggen.go        |  10 ++-
 src/cmd/compile/internal/x86/ggen.go          |   4 +-
 src/cmd/compile/internal/x86/reg.go           |   2 -
 src/cmd/go/alldocs.go                         |   9 ++-
 src/cmd/go/build.go                           |   2 +-
 src/cmd/go/go_test.go                         |  35 +++++++++
 src/cmd/go/help.go                            |   2 +-
 src/cmd/go/list.go                            |   7 +-
 src/cmd/go/main.go                            |   5 +-
 src/cmd/go/note_test.go                       |  26 +++++-
 src/cmd/go/pkg.go                             |  12 +--
 src/cmd/go/test.go                            |   2 +-
 src/cmd/go/testdata/testvendor2/src/p/p.go    |   3 +
 src/cmd/go/testdata/testvendor2/vendor/x/x.go |   1 +
 src/cmd/go/testflag.go                        |   1 +
 src/cmd/go/vcs.go                             |   2 +-
 src/cmd/go/vendor_test.go                     |  12 +++
 src/cmd/link/internal/ld/data.go              |  13 ++-
 src/cmd/trace/trace.go                        |   4 +-
 src/cmd/vet/asmdecl.go                        |  24 +++---
 src/cmd/yacc/yacc.go                          |  11 ++-
 src/fmt/scan.go                               |   1 -
 src/fmt/scan_test.go                          |  28 +++++++
 src/net/cgo_unix.go                           |   5 ++
 src/net/conf.go                               |   8 +-
 src/net/http/server.go                        |   7 +-
 src/net/http/transport.go                     |  80 ++++++++++++++++---
 src/net/lookup_test.go                        | 109 ++++++++++++++++++++++++++
 src/net/lookup_unix.go                        |  27 ++++---
 src/net/mail/message.go                       |   9 ++-
 src/net/mail/message_test.go                  |   8 ++
 src/net/net.go                                |  40 ++++++++++
 src/net/non_unix_test.go                      |  11 +++
 src/net/unix_test.go                          |  25 ++++++
 src/runtime/asm_arm.s                         |   5 ++
 src/runtime/mbitmap.go                        |   9 +++
 src/runtime/os1_darwin.go                     |   9 ++-
 src/runtime/os_darwin_arm.go                  |   9 ++-
 src/runtime/os_freebsd_arm.go                 |   9 ++-
 src/runtime/os_linux_arm.go                   |   1 -
 src/runtime/os_nacl_arm.go                    |   8 +-
 src/runtime/os_netbsd_arm.go                  |   9 ++-
 src/runtime/os_openbsd_arm.go                 |   9 ++-
 src/runtime/panic.go                          |   2 +-
 src/runtime/proc1.go                          |  18 ++++-
 src/runtime/runtime2.go                       |   2 +
 src/runtime/stubs.go                          |  15 +++-
 src/sort/sort.go                              |   2 +-
 test/fixedbugs/issue12133.go                  |  26 ++++++
 62 files changed, 640 insertions(+), 154 deletions(-)

diff --git a/VERSION b/VERSION
index c548f34..661b4f9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.5rc1
\ No newline at end of file
+go1.5
\ No newline at end of file
diff --git a/doc/asm.html b/doc/asm.html
index ba88811..c992e14 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -741,10 +741,10 @@ Addressing modes:
 
 </ul>
 
-<h3 id="ppc64">Power 64, a.k.a. ppc64</h3>
+<h3 id="ppc64">64-bit PowerPC, a.k.a. ppc64</h3>
 
 <p>
-The Power 64 port is in an experimental state.
+The 64-bit PowerPC port is in an experimental state.
 </p>
 
 <p>
diff --git a/doc/contrib.html b/doc/contrib.html
index c286abc..4839035 100644
--- a/doc/contrib.html
+++ b/doc/contrib.html
@@ -34,6 +34,7 @@ We encourage all Go users to subscribe to
 <p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
 
 <ul>
+	<li><a href="/doc/go1.5">Go 1.5</a> <small>(August 2015)</small></li>
 	<li><a href="/doc/go1.4">Go 1.4</a> <small>(December 2014)</small></li>
 	<li><a href="/doc/go1.3">Go 1.3</a> <small>(June 2014)</small></li>
 	<li><a href="/doc/go1.2">Go 1.2</a> <small>(December 2013)</small></li>
diff --git a/doc/devel/release.html b/doc/devel/release.html
index ee6d3e0..7d72c8d 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -12,6 +12,13 @@ git pull
 git checkout <i>release-branch</i>
 </pre>
 
+<h2 id="go1.5">go1.5 (released 2015/08/19)</h2>
+
+<p>
+Go 1.5 is a major release of Go.
+Read the <a href="/doc/go1.5">Go 1.5 Release Notes</a> for more information.
+</p>
+
 <h2 id="go1.4">go1.4 (released 2014/12/10)</h2>
 
 <p>
diff --git a/doc/go1.5.html b/doc/go1.5.html
index 70ce94e..4e5832d 100644
--- a/doc/go1.5.html
+++ b/doc/go1.5.html
@@ -83,7 +83,8 @@ time the release dates more conveniently.
 Due to an oversight, the rule that allowed the element type to be elided from slice literals was not
 applied to map keys.
 This has been <a href="/cl/2591">corrected</a> in Go 1.5.
-An example will make this clear: as of Go 1.5, this map literal,
+An example will make this clear.
+As of Go 1.5, this map literal,
 </p>
 
 <pre>
@@ -182,7 +183,7 @@ Details of the new collector were presented in a
 <p>
 In Go 1.5, the order in which goroutines are scheduled has been changed.
 The properties of the scheduler were never defined by the language,
-but programs that depended on the scheduling order may be broken
+but programs that depend on the scheduling order may be broken
 by this change.
 We have seen a few (erroneous) programs affected by this change.
 If you have programs that implicitly depend on the scheduling
@@ -194,7 +195,7 @@ Another potentially breaking change is that the runtime now
 sets the default number of threads to run simultaneously,
 defined by <code>GOMAXPROCS</code>, to the number
 of cores available on the CPU.
-In prior releases it defaulted to 1.
+In prior releases the default was 1.
 Programs that do not expect to run with multiple cores may
 break inadvertently.
 They can be updated by removing the restriction or by setting
@@ -236,8 +237,8 @@ is only supported using external linking.
 </p>
 
 <p>
-Also available as experiments are <code>ppc64</code> (IBM Power 64)
-and <code>ppc64le</code> (IBM Power 64, little-endian).
+Also available as experiments are <code>ppc64</code>
+and <code>ppc64le</code> (64-bit PowerPC, big- and little-endian).
 Both these ports support <code>cgo</code> but
 only with internal linking.
 </p>
@@ -247,8 +248,8 @@ On FreeBSD, Go 1.5 requires FreeBSD 8-STABLE+ because of its new use of the <cod
 </p>
 
 <p>
-On NaCl, Go 1.5 requires SDK version pepper-39 or above because it now uses the
-<code>get_random_bytes</code> system call.
+On NaCl, Go 1.5 requires SDK version pepper-41. Later pepper versions are not
+compatible due to the removal of the sRPC subsystem from the NaCl runtime.
 </p>
 
 <p>
@@ -292,7 +293,7 @@ The old names are gone; the new tools are available through the <code>go</code>
 mechanism as <code>go tool compile</code>,
 <code>go tool asm</code>,
 <code>and go tool link</code>.
-Also, the file suffixes <code>.6</code>, <code>.8</code> etc. for the
+Also, the file suffixes <code>.6</code>, <code>.8</code>, etc. for the
 intermediate object files are also gone; now they are just plain <code>.o</code> files.
 </p>
 
@@ -512,7 +513,7 @@ A new <code>cmd</code> wildcard covers the commands.
 <li>
 A new <code>-asmflags</code> build option
 sets flags to pass to the assembler.
-However, 
+However,
 the <code>-ccflags</code> build option has been dropped;
 it was specific to the old, now deleted C compiler .
 </li>
@@ -523,14 +524,6 @@ sets the build mode, described above.
 </li>
 
 <li>
-An <code>-asmflags</code> build option has been added to provide
-flags to the assembler.
-However,
-the <code>-ccflags</code> build option has been dropped;
-it was specific to the old, now deleted C compiler .
-</li>
-
-<li>
 A new <code>-pkgdir</code> build option
 sets the location of installed package archives,
 to help isolate custom builds.
@@ -546,7 +539,7 @@ This acts as a custom replacement for <code>go tool</code>.
 <li>
 The <code>test</code> subcommand now has a <code>-count</code>
 flag to specify how many times to run each test and benchmark.
-<a href="/pkg/testing/"><code>testing</code></a> package
+The <a href="/pkg/testing/"><code>testing</code></a> package
 does the work here, through by the <code>-test.count</code> flag.
 </li>
 
@@ -823,7 +816,7 @@ method to discard data from the input.
 </li>
 
 <li>
-Also in the <a href="/pkg/bytes/"><code>bytes</code></a> package,
+In the <a href="/pkg/bytes/"><code>bytes</code></a> package,
 the <a href="/pkg/bytes/#Buffer"><code>Buffer</code></a> type
 now has a <a href="/pkg/bytes/#Buffer.Cap"><code>Cap</code></a> method
 that reports the number of bytes allocated within the buffer.
@@ -960,7 +953,7 @@ also now supports decoding of DWARF line tables.
 
 <li>
 The <a href="/pkg/debug/elf/"><code>debug/elf</code></a>
-package now has support for the 64-bit Power architecture.
+package now has support for the 64-bit PowerPC architecture.
 </li>
 
 <li>
@@ -1032,14 +1025,14 @@ To update, run
 In the <a href="/pkg/image/"><code>image</code></a> package,
 the <a href="/pkg/image/#Rectangle"><code>Rectangle</code></a> type
 now implements the <a href="/pkg/image/#Image"><code>Image</code></a> interface,
-mask image when drawing.
+so a <code>Rectangle</code> can serve as a mask when drawing.
 </li>
 
 <li>
 Also in the <a href="/pkg/image/"><code>image</code></a> package,
 to assist in the handling of some JPEG images,
 there is now support for 4:1:1 and 4:1:0 YCbCr subsampling and basic
-CMYK support, represented by the new image.CMYK struct.
+CMYK support, represented by the new <code>image.CMYK</code> struct.
 </li>
 
 <li>
@@ -1062,7 +1055,7 @@ Because of the echo property of the old code, the operation
 In Go 1.5, that operation may yield a different value.
 The correct code is, and always was, to select the high 8 bits:
 <code>uint8(r>>8)</code>.
-Incidentally, <code>image/draw</code> package
+Incidentally, the <code>image/draw</code> package
 provides better support for such conversions; see
 <a href="https://blog.golang.org/go-imagedraw-package">this blog post</a>
 for more information.
@@ -1095,9 +1088,8 @@ uses a caller-provided buffer, permitting control of allocation and buffer size.
 The <a href="/pkg/log/"><code>log</code></a> package
 has a new <a href="/pkg/log/#LUTC"><code>LUTC</code></a> flag
 that causes time stamps to be printed in the UTC time zone.
-It also adds a <a href="/pkg/log/#SetOutput"><code>SetOutput</code></a> function
-to set the output destination for the standard logger
-and a corresponding method for user-created loggers.
+It also adds a <a href="/pkg/log/#Logger.SetOutput"><code>SetOutput</code></a> method
+for user-created loggers.
 </li>
 
 <li>
@@ -1109,7 +1101,7 @@ but now correctly according to the IEEE754 definition of NaNs.
 <li>
 The <a href="/pkg/math/big/"><code>math/big</code></a> package
 adds a new <a href="/pkg/math/big/#Jacobi"><code>Jacobi</code></a>
-function for integers and a new method
+function for integers and a new
 <a href="/pkg/math/big/#Int.ModSqrt"><code>ModSqrt</code></a>
 method for the <a href="/pkg/math/big/#Int"><code>Int</code></a> type.
 </li>
@@ -1201,7 +1193,7 @@ variable.
 
 <li>
 The <a href="/pkg/net/mail/"><code>net/mail</code></a> package
-adds a <a href="/pkg/net/mail/#AddressParser"><code>AddressParser</code></a>
+adds an <a href="/pkg/net/mail/#AddressParser"><code>AddressParser</code></a>
 type that can parse mail addresses.
 </li>
 
@@ -1252,11 +1244,11 @@ but is otherwise unnecessary as strings support comparison natively.
 </li>
 
 <li>
-The <a href="/pkg/sync/#WaitGroup"><code>WaitGroup</code></a> function in
+The <a href="/pkg/sync/#WaitGroup"><code>WaitGroup</code></a> implementation in
 package <a href="/pkg/sync/"><code>sync</code></a>
 now diagnoses code that races a call to <a href="/pkg/sync/#WaitGroup.Add"><code>Add</code></a>
 against a return from <a href="/pkg/sync/#WaitGroup.Wait"><code>Wait</code></a>.
-If it detects this condition, <code>WaitGroup</code> panics.
+If it detects this condition, the implementation panics.
 </li>
 
 <li>
@@ -1288,7 +1280,7 @@ precision.
 <li>
 Also in the <a href="/pkg/text/template/"><code>text/template</code></a> and
 <a href="/pkg/html/template/"><code>html/template</code></a> packages,
-a new <a href="/pkg/text/template/#Option"><code>Option</code></a> type
+a new <a href="/pkg/text/template/#Template.Option"><code>Option</code></a> method
 allows customization of the behavior of the template during execution.
 The sole implemented option allows control over how a missing key is
 handled when indexing a map.
diff --git a/doc/install.html b/doc/install.html
index 9264f3a..e9f0f0d 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -33,11 +33,11 @@ system and architecture, try
 <h2 id="requirements">System requirements</h2>
 
 <p>
-The <code>gc</code> compiler supports the following operating systems and
-architectures. Please ensure your system meets these requirements before
-proceeding. If your OS or architecture is not on the list, it's possible that
-<code>gccgo</code> might support your setup; see
-<a href="/doc/install/gccgo">Setting up and using gccgo</a> for details.
+Go binary distributions are available for these supported operating systems and architectures.
+Please ensure your system meets these requirements before proceeding.
+If your OS or architecture is not on the list, you may be able to
+<a href="/doc/install/source">install from source</a> or
+<a href="/doc/install/gccgo">use gccgo instead</a>.
 </p>
 
 <table class="codetable" frame="border" summary="requirements">
@@ -47,9 +47,9 @@ proceeding. If your OS or architecture is not on the list, it's possible that
 <th align="center">Notes</th>
 </tr>
 <tr><td colspan="3"><hr></td></tr>
-<tr><td>FreeBSD 8-STABLE or later</td> <td>amd64, 386, arm</td> <td>Debian GNU/kFreeBSD not supported; FreeBSD/ARM needs FreeBSD 10 or later</td></tr>
-<tr><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm</td> <td>CentOS/RHEL 5.x not supported; no binary distribution for ARM yet</td></tr>
-<tr><td>Mac OS X 10.7 or later</td> <td>amd64</td> <td>use the gcc<sup>†</sup> that comes with Xcode<sup>‡</sup></td></tr>
+<tr><td>FreeBSD 8-STABLE or later</td> <td>amd64</td> <td>Debian GNU/kFreeBSD not supported</td></tr>
+<tr><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm</td> <td>CentOS/RHEL 5.x not supported; install from source for ARM</td></tr>
+<tr><td>Mac OS X 10.7 or later</td> <td>amd64</td> <td>use the clang or gcc<sup>†</sup> that comes with Xcode<sup>‡</sup></td></tr>
 <tr><td>Windows XP or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>†</sup>. No need for cygwin or msys.</td></tr>
 </table>
 
diff --git a/src/cmd/compile/internal/amd64/ggen.go b/src/cmd/compile/internal/amd64/ggen.go
index 6425633..65cf694 100644
--- a/src/cmd/compile/internal/amd64/ggen.go
+++ b/src/cmd/compile/internal/amd64/ggen.go
@@ -306,7 +306,7 @@ func dodiv(op int, nl *gc.Node, nr *gc.Node, res *gc.Node) {
  * known to be dead.
  */
 func savex(dr int, x *gc.Node, oldx *gc.Node, res *gc.Node, t *gc.Type) {
-	r := reg[dr]
+	r := uint8(gc.GetReg(dr))
 
 	// save current ax and dx if they are live
 	// and not the destination
@@ -319,14 +319,14 @@ func savex(dr int, x *gc.Node, oldx *gc.Node, res *gc.Node, t *gc.Type) {
 		gmove(x, oldx)
 		x.Type = t
 		oldx.Etype = r // squirrel away old r value
-		reg[dr] = 1
+		gc.SetReg(dr, 1)
 	}
 }
 
 func restx(x *gc.Node, oldx *gc.Node) {
 	if oldx.Op != 0 {
 		x.Type = gc.Types[gc.TINT64]
-		reg[x.Reg] = oldx.Etype
+		gc.SetReg(int(x.Reg), int(oldx.Etype))
 		gmove(oldx, x)
 		gc.Regfree(oldx)
 	}
@@ -411,7 +411,7 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
 		nr = &n5
 	}
 
-	rcx := int(reg[x86.REG_CX])
+	rcx := gc.GetReg(x86.REG_CX)
 	var n1 gc.Node
 	gc.Nodreg(&n1, gc.Types[gc.TUINT32], x86.REG_CX)
 
diff --git a/src/cmd/compile/internal/amd64/reg.go b/src/cmd/compile/internal/amd64/reg.go
index 7d4f406..8fab639 100644
--- a/src/cmd/compile/internal/amd64/reg.go
+++ b/src/cmd/compile/internal/amd64/reg.go
@@ -40,8 +40,6 @@ const (
 	NREGVAR = 32
 )
 
-var reg [x86.MAXREG]uint8
-
 var regname = []string{
 	".AX",
 	".CX",
diff --git a/src/cmd/compile/internal/arm64/ggen.go b/src/cmd/compile/internal/arm64/ggen.go
index 6b0b40e..cba4d99 100644
--- a/src/cmd/compile/internal/arm64/ggen.go
+++ b/src/cmd/compile/internal/arm64/ggen.go
@@ -418,15 +418,12 @@ func clearfat(nl *gc.Node) {
 	c := uint64(w % 8) // bytes
 	q := uint64(w / 8) // dwords
 
-	if reg[arm64.REGRT1-arm64.REG_R0] > 0 {
-		gc.Fatal("R%d in use during clearfat", arm64.REGRT1-arm64.REG_R0)
-	}
-
 	var r0 gc.Node
 	gc.Nodreg(&r0, gc.Types[gc.TUINT64], arm64.REGZERO)
 	var dst gc.Node
+
+	// REGRT1 is reserved on arm64, see arm64/gsubr.go.
 	gc.Nodreg(&dst, gc.Types[gc.Tptr], arm64.REGRT1)
-	reg[arm64.REGRT1-arm64.REG_R0]++
 	gc.Agen(nl, &dst)
 
 	var boff uint64
@@ -484,8 +481,6 @@ func clearfat(nl *gc.Node) {
 		p.To.Type = obj.TYPE_MEM
 		p.To.Offset = int64(t + boff)
 	}
-
-	reg[arm64.REGRT1-arm64.REG_R0]--
 }
 
 // Called after regopt and peep have run.
diff --git a/src/cmd/compile/internal/arm64/reg.go b/src/cmd/compile/internal/arm64/reg.go
index 7bc756b..b84359a 100644
--- a/src/cmd/compile/internal/arm64/reg.go
+++ b/src/cmd/compile/internal/arm64/reg.go
@@ -39,8 +39,6 @@ const (
 	NREGVAR = 64 /* 32 general + 32 floating */
 )
 
-var reg [arm64.NREG + arm64.NFREG]uint8
-
 var regname = []string{
 	".R0",
 	".R1",
diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go
index 14dc927..2c575f3 100644
--- a/src/cmd/compile/internal/gc/gsubr.go
+++ b/src/cmd/compile/internal/gc/gsubr.go
@@ -602,6 +602,13 @@ func unpatch(p *obj.Prog) *obj.Prog {
 var reg [100]int       // count of references to reg
 var regstk [100][]byte // allocation sites, when -v is given
 
+func GetReg(r int) int {
+	return reg[r-Thearch.REGMIN]
+}
+func SetReg(r, v int) {
+	reg[r-Thearch.REGMIN] = v
+}
+
 func ginit() {
 	for r := range reg {
 		reg[r] = 1
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index dc2ba75..befe3b2 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -2532,7 +2532,7 @@ func lookdot(n *Node, t *Type, dostrcmp int) *Type {
 		n.Xoffset = f1.Width
 		n.Type = f1.Type
 		if obj.Fieldtrack_enabled > 0 {
-			dotField[typeSym{t, s}] = f1
+			dotField[typeSym{t.Orig, s}] = f1
 		}
 		if t.Etype == TINTER {
 			if Isptr[n.Left.Type.Etype] {
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 91c0a47..ce73018 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -3873,7 +3873,7 @@ func usefield(n *Node) {
 	if Isptr[t.Etype] {
 		t = t.Type
 	}
-	field := dotField[typeSym{t, n.Right.Sym}]
+	field := dotField[typeSym{t.Orig, n.Right.Sym}]
 	if field == nil {
 		Fatal("usefield %v %v without paramfld", n.Left.Type, n.Right.Sym)
 	}
diff --git a/src/cmd/compile/internal/ppc64/ggen.go b/src/cmd/compile/internal/ppc64/ggen.go
index 1b936b8..5b282eb 100644
--- a/src/cmd/compile/internal/ppc64/ggen.go
+++ b/src/cmd/compile/internal/ppc64/ggen.go
@@ -71,7 +71,10 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
 		for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
 			p = appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, 8+frame+lo+i)
 		}
-	} else if cnt <= int64(128*gc.Widthptr) {
+		// TODO(dfc): https://golang.org/issue/12108
+		// If DUFFZERO is used inside a tail call (see genwrapper) it will
+		// overwrite the link register.
+	} else if false && cnt <= int64(128*gc.Widthptr) {
 		p = appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, 8+frame+lo-8, obj.TYPE_REG, ppc64.REGRT1, 0)
 		p.Reg = ppc64.REGSP
 		p = appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
@@ -442,7 +445,10 @@ func clearfat(nl *gc.Node) {
 
 		// The loop leaves R3 on the last zeroed dword
 		boff = 8
-	} else if q >= 4 {
+		// TODO(dfc): https://golang.org/issue/12108
+		// If DUFFZERO is used inside a tail call (see genwrapper) it will
+		// overwrite the link register.
+	} else if false && q >= 4 {
 		p := gins(ppc64.ASUB, nil, &dst)
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = 8
diff --git a/src/cmd/compile/internal/x86/ggen.go b/src/cmd/compile/internal/x86/ggen.go
index dabc139..ae9881d 100644
--- a/src/cmd/compile/internal/x86/ggen.go
+++ b/src/cmd/compile/internal/x86/ggen.go
@@ -319,7 +319,7 @@ func dodiv(op int, nl *gc.Node, nr *gc.Node, res *gc.Node, ax *gc.Node, dx *gc.N
 }
 
 func savex(dr int, x *gc.Node, oldx *gc.Node, res *gc.Node, t *gc.Type) {
-	r := int(reg[dr])
+	r := gc.GetReg(dr)
 	gc.Nodreg(x, gc.Types[gc.TINT32], dr)
 
 	// save current ax and dx if they are live
@@ -408,7 +408,7 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
 	var oldcx gc.Node
 	var cx gc.Node
 	gc.Nodreg(&cx, gc.Types[gc.TUINT32], x86.REG_CX)
-	if reg[x86.REG_CX] > 1 && !gc.Samereg(&cx, res) {
+	if gc.GetReg(x86.REG_CX) > 1 && !gc.Samereg(&cx, res) {
 		gc.Tempname(&oldcx, gc.Types[gc.TUINT32])
 		gmove(&cx, &oldcx)
 	}
diff --git a/src/cmd/compile/internal/x86/reg.go b/src/cmd/compile/internal/x86/reg.go
index 8c97171..b3a5fdf 100644
--- a/src/cmd/compile/internal/x86/reg.go
+++ b/src/cmd/compile/internal/x86/reg.go
@@ -37,8 +37,6 @@ const (
 	NREGVAR = 16 /* 8 integer + 8 floating */
 )
 
-var reg [x86.MAXREG]uint8
-
 var regname = []string{
 	".ax",
 	".cx",
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 512ed61..6077d93 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -521,9 +521,10 @@ List lists the packages named by the import paths, one per line.
 
 The default output shows the package import path:
 
-    code.google.com/p/google-api-go-client/books/v1
-    code.google.com/p/goauth2/oauth
-    code.google.com/p/sqlite
+    bytes
+    encoding/json
+    github.com/gorilla/mux
+    golang.org/x/net/html
 
 The -f flag specifies an alternate format for the list, using the
 syntax of package template.  The default output is equivalent to -f
@@ -1284,7 +1285,7 @@ By convention, this is arranged by starting each path with a
 unique prefix that belongs to you.  For example, paths used
 internally at Google all begin with 'google', and paths
 denoting remote repositories begin with the path to the code,
-such as 'code.google.com/p/project'.
+such as 'github.com/user/repo'.
 
 As a special case, if the package list is a list of .go files from a
 single directory, the command is applied to a single synthesized
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 718edd2..b7c7e05 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -1880,7 +1880,7 @@ func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...inter
 		cmd.Stdout = &buf
 		cmd.Stderr = &buf
 		cmd.Dir = dir
-		cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir))
+		cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir, os.Environ()))
 		err := cmd.Run()
 
 		// cmd.Run will fail on Unix if some other process has the binary
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 5b0f278..77b2628 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -2294,6 +2294,21 @@ func TestIssue11709(t *testing.T) {
 	tg.run("run", tg.path("run.go"))
 }
 
+func TestIssue12096(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.tempFile("test_test.go", `
+		package main
+		import ("os"; "testing")
+		func TestEnv(t *testing.T) {
+			if os.Getenv("TERM") != "" {
+				t.Fatal("TERM is set")
+			}
+		}`)
+	tg.unsetenv("TERM")
+	tg.run("test", tg.path("test_test.go"))
+}
+
 func TestGoBuildOutput(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -2352,3 +2367,23 @@ func TestGoBuildOutput(t *testing.T) {
 	tg.runFail("build", "-o", "whatever", "cmd/gofmt", "sync/atomic")
 	tg.grepStderr("multiple packages", "did not reject -o with multiple packages")
 }
+
+func TestGoBuildARM(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping cross-compile in short mode")
+	}
+
+	tg := testgo(t)
+	defer tg.cleanup()
+
+	tg.makeTempdir()
+	tg.cd(tg.path("."))
+
+	tg.setenv("GOARCH", "arm")
+	tg.setenv("GOOS", "linux")
+	tg.setenv("GOARM", "5")
+	tg.tempFile("hello.go", `package main
+		func main() {}`)
+	tg.run("build", "hello.go")
+	tg.grepStderrNot("unable to find math.a", "did not build math.a correctly")
+}
diff --git a/src/cmd/go/help.go b/src/cmd/go/help.go
index 0bc5ef9..5dff267 100644
--- a/src/cmd/go/help.go
+++ b/src/cmd/go/help.go
@@ -77,7 +77,7 @@ By convention, this is arranged by starting each path with a
 unique prefix that belongs to you.  For example, paths used
 internally at Google all begin with 'google', and paths
 denoting remote repositories begin with the path to the code,
-such as 'code.google.com/p/project'.
+such as 'github.com/user/repo'.
 
 As a special case, if the package list is a list of .go files from a
 single directory, the command is applied to a single synthesized
diff --git a/src/cmd/go/list.go b/src/cmd/go/list.go
index f59c82e..35c7cc4 100644
--- a/src/cmd/go/list.go
+++ b/src/cmd/go/list.go
@@ -21,9 +21,10 @@ List lists the packages named by the import paths, one per line.
 
 The default output shows the package import path:
 
-    code.google.com/p/google-api-go-client/books/v1
-    code.google.com/p/goauth2/oauth
-    code.google.com/p/sqlite
+    bytes
+    encoding/json
+    github.com/gorilla/mux
+    golang.org/x/net/html
 
 The -f flag specifies an alternate format for the list, using the
 syntax of package template.  The default output is equivalent to -f
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index 88a9441..8ebde89 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -446,11 +446,10 @@ func runOut(dir string, cmdargs ...interface{}) []byte {
 // The environment is the current process's environment
 // but with an updated $PWD, so that an os.Getwd in the
 // child will be faster.
-func envForDir(dir string) []string {
-	env := os.Environ()
+func envForDir(dir string, base []string) []string {
 	// Internally we only use rooted paths, so dir is rooted.
 	// Even if dir is not rooted, no harm done.
-	return mergeEnvLists([]string{"PWD=" + dir}, env)
+	return mergeEnvLists([]string{"PWD=" + dir}, base)
 }
 
 // mergeEnvLists merges the two environment lists such that
diff --git a/src/cmd/go/note_test.go b/src/cmd/go/note_test.go
index fb25f94..3d64451 100644
--- a/src/cmd/go/note_test.go
+++ b/src/cmd/go/note_test.go
@@ -5,7 +5,8 @@
 package main_test
 
 import (
-	"cmd/go"
+	main "cmd/go"
+	"runtime"
 	"testing"
 )
 
@@ -22,4 +23,27 @@ func TestNoteReading(t *testing.T) {
 	if id != buildID {
 		t.Fatalf("buildID in hello binary = %q, want %q", id, buildID)
 	}
+
+	if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le" {
+		t.Skipf("skipping - golang.org/issue/11184")
+	}
+
+	switch runtime.GOOS {
+	case "plan9":
+		// no external linking
+		t.Logf("no external linking - skipping linkmode=external test")
+
+	case "solaris":
+		t.Logf("skipping - golang.org/issue/12178")
+
+	default:
+		tg.run("build", "-ldflags", "-buildid="+buildID+" -linkmode=external", "-o", tg.path("hello.exe"), tg.path("hello.go"))
+		id, err := main.ReadBuildIDFromBinary(tg.path("hello.exe"))
+		if err != nil {
+			t.Fatalf("reading build ID from hello binary (linkmode=external): %v", err)
+		}
+		if id != buildID {
+			t.Fatalf("buildID in hello binary = %q, want %q (linkmode=external)", id, buildID)
+		}
+	}
 }
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 6b78a47..61e3d8d 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -416,7 +416,7 @@ func vendoredImportPath(parent *Package, path string) (found string, searched []
 		return path, nil
 	}
 	dir := filepath.Clean(parent.Dir)
-	root := filepath.Clean(parent.Root)
+	root := filepath.Join(parent.Root, "src")
 	if !hasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator {
 		fatalf("invalid vendoredImportPath: dir=%q root=%q separator=%q", dir, root, string(filepath.Separator))
 	}
@@ -836,7 +836,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
 			importPaths = append(importPaths, "runtime/race")
 		}
 		// On ARM with GOARM=5, everything depends on math for the link.
-		if p.ImportPath == "main" && goarch == "arm" {
+		if p.Name == "main" && goarch == "arm" {
 			importPaths = append(importPaths, "math")
 		}
 	}
@@ -1796,10 +1796,10 @@ func ReadBuildIDFromBinary(filename string) (id string, err error) {
 		return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDUnknown}
 	}
 
-	// Read the first 8 kB of the binary file.
+	// Read the first 16 kB of the binary file.
 	// That should be enough to find the build ID.
 	// In ELF files, the build ID is in the leading headers,
-	// which are typically less than 4 kB, not to mention 8 kB.
+	// which are typically less than 4 kB, not to mention 16 kB.
 	// On other systems, we're trying to read enough that
 	// we get the beginning of the text segment in the read.
 	// The offset where the text segment begins in a hello
@@ -1807,7 +1807,7 @@ func ReadBuildIDFromBinary(filename string) (id string, err error) {
 	//
 	//	Plan 9: 0x20
 	//	Windows: 0x600
-	//	Mach-O: 0x1000
+	//	Mach-O: 0x2000
 	//
 	f, err := os.Open(filename)
 	if err != nil {
@@ -1815,7 +1815,7 @@ func ReadBuildIDFromBinary(filename string) (id string, err error) {
 	}
 	defer f.Close()
 
-	data := make([]byte, 8192)
+	data := make([]byte, 16*1024)
 	_, err = io.ReadFull(f, data)
 	if err == io.ErrUnexpectedEOF {
 		err = nil
diff --git a/src/cmd/go/test.go b/src/cmd/go/test.go
index 0ba1883..ba1ab82 100644
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -1027,7 +1027,7 @@ func (b *builder) runTest(a *action) error {
 
 	cmd := exec.Command(args[0], args[1:]...)
 	cmd.Dir = a.p.Dir
-	cmd.Env = envForDir(cmd.Dir)
+	cmd.Env = envForDir(cmd.Dir, origEnv)
 	var buf bytes.Buffer
 	if testStreamOutput {
 		cmd.Stdout = os.Stdout
diff --git a/src/cmd/go/testdata/testvendor2/src/p/p.go b/src/cmd/go/testdata/testvendor2/src/p/p.go
new file mode 100644
index 0000000..220b2b2
--- /dev/null
+++ b/src/cmd/go/testdata/testvendor2/src/p/p.go
@@ -0,0 +1,3 @@
+package p
+
+import "x"
diff --git a/src/cmd/go/testdata/testvendor2/vendor/x/x.go b/src/cmd/go/testdata/testvendor2/vendor/x/x.go
new file mode 100644
index 0000000..823aafd
--- /dev/null
+++ b/src/cmd/go/testdata/testvendor2/vendor/x/x.go
@@ -0,0 +1 @@
+package x
diff --git a/src/cmd/go/testflag.go b/src/cmd/go/testflag.go
index ee4ab18..1f3e3d3 100644
--- a/src/cmd/go/testflag.go
+++ b/src/cmd/go/testflag.go
@@ -36,6 +36,7 @@ var testFlagDefn = []*testFlagSpec{
 	{name: "cover", boolVar: &testCover},
 	{name: "covermode"},
 	{name: "coverpkg"},
+	{name: "exec"},
 
 	// passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v.
 	{name: "bench", passToTest: true},
diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
index 2ee1057..28a7540 100644
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -344,7 +344,7 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
 
 	cmd := exec.Command(v.cmd, args...)
 	cmd.Dir = dir
-	cmd.Env = envForDir(cmd.Dir)
+	cmd.Env = envForDir(cmd.Dir, os.Environ())
 	if buildX {
 		fmt.Printf("cd %s\n", dir)
 		fmt.Printf("%s %s\n", v.cmd, strings.Join(args, " "))
diff --git a/src/cmd/go/vendor_test.go b/src/cmd/go/vendor_test.go
index 611aceb..1e8cf9c 100644
--- a/src/cmd/go/vendor_test.go
+++ b/src/cmd/go/vendor_test.go
@@ -244,3 +244,15 @@ func TestVendorList(t *testing.T) {
 	tg.run("list", "-f", `{{join .XTestImports "\n"}}`, "github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx3")
 	tg.grepStdout("go-get-issue-11864/vendor/vendor.org/tx3", "did not find vendor-expanded tx3")
 }
+
+func TestVendor12156(t *testing.T) {
+	// Former index out of range panic.
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata/testvendor2"))
+	tg.setenv("GO15VENDOREXPERIMENT", "1")
+	tg.cd(filepath.Join(tg.pwd(), "testdata/testvendor2/src/p"))
+	tg.runFail("build", "p.go")
+	tg.grepStderrNot("panic", "panicked")
+	tg.grepStderr(`cannot find package "x"`, "wrong error")
+}
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 33f250d..55b12e5 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -778,7 +778,6 @@ func Codeblk(addr int64, size int64) {
 	}
 
 	eaddr := addr + size
-	var n int64
 	var q []byte
 	for ; sym != nil; sym = sym.Next {
 		if !sym.Reachable {
@@ -797,20 +796,18 @@ func Codeblk(addr int64, size int64) {
 		}
 
 		fmt.Fprintf(&Bso, "%.6x\t%-20s\n", uint64(int64(addr)), sym.Name)
-		n = sym.Size
 		q = sym.P
 
-		for n >= 16 {
-			fmt.Fprintf(&Bso, "%.6x\t%-20.16I\n", uint64(addr), q)
+		for len(q) >= 16 {
+			fmt.Fprintf(&Bso, "%.6x\t% x\n", uint64(addr), q[:16])
 			addr += 16
 			q = q[16:]
-			n -= 16
 		}
 
-		if n > 0 {
-			fmt.Fprintf(&Bso, "%.6x\t%-20.*I\n", uint64(addr), int(n), q)
+		if len(q) > 0 {
+			fmt.Fprintf(&Bso, "%.6x\t% x\n", uint64(addr), q)
+			addr += int64(len(q))
 		}
-		addr += n
 	}
 
 	if addr < eaddr {
diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go
index 0d2451b..e6eb320 100644
--- a/src/cmd/trace/trace.go
+++ b/src/cmd/trace/trace.go
@@ -10,8 +10,8 @@ import (
 	"internal/trace"
 	"log"
 	"net/http"
-	"os"
 	"path/filepath"
+	"runtime"
 	"strconv"
 	"strings"
 )
@@ -63,7 +63,7 @@ var templTrace = `
 // httpTraceViewerHTML serves static part of trace-viewer.
 // This URL is queried from templTrace HTML.
 func httpTraceViewerHTML(w http.ResponseWriter, r *http.Request) {
-	http.ServeFile(w, r, filepath.Join(os.Getenv("GOROOT"), "misc", "trace", "trace_viewer_lean.html"))
+	http.ServeFile(w, r, filepath.Join(runtime.GOROOT(), "misc", "trace", "trace_viewer_lean.html"))
 }
 
 // httpJsonTrace serves json trace, requested from within templTrace HTML.
diff --git a/src/cmd/vet/asmdecl.go b/src/cmd/vet/asmdecl.go
index 6bdfdbf..e4a9871 100644
--- a/src/cmd/vet/asmdecl.go
+++ b/src/cmd/vet/asmdecl.go
@@ -58,13 +58,13 @@ type asmVar struct {
 }
 
 var (
-	asmArch386       = asmArch{"386", 4, 4, 4, false, "SP", false}
-	asmArchArm       = asmArch{"arm", 4, 4, 4, false, "R13", true}
-	asmArchArm64     = asmArch{"arm64", 8, 8, 8, false, "RSP", true}
-	asmArchAmd64     = asmArch{"amd64", 8, 8, 8, false, "SP", false}
-	asmArchAmd64p32  = asmArch{"amd64p32", 4, 4, 8, false, "SP", false}
-	asmArchPower64   = asmArch{"power64", 8, 8, 8, true, "R1", true}
-	asmArchPower64LE = asmArch{"power64le", 8, 8, 8, false, "R1", true}
+	asmArch386      = asmArch{"386", 4, 4, 4, false, "SP", false}
+	asmArchArm      = asmArch{"arm", 4, 4, 4, false, "R13", true}
+	asmArchArm64    = asmArch{"arm64", 8, 8, 8, false, "RSP", true}
+	asmArchAmd64    = asmArch{"amd64", 8, 8, 8, false, "SP", false}
+	asmArchAmd64p32 = asmArch{"amd64p32", 4, 4, 8, false, "SP", false}
+	asmArchPpc64    = asmArch{"ppc64", 8, 8, 8, true, "R1", true}
+	asmArchPpc64LE  = asmArch{"ppc64le", 8, 8, 8, false, "R1", true}
 
 	arches = []*asmArch{
 		&asmArch386,
@@ -72,8 +72,8 @@ var (
 		&asmArchArm64,
 		&asmArchAmd64,
 		&asmArchAmd64p32,
-		&asmArchPower64,
-		&asmArchPower64LE,
+		&asmArchPpc64,
+		&asmArchPpc64LE,
 	}
 )
 
@@ -86,7 +86,7 @@ var (
 	asmUnnamedFP = re(`[^+\-0-9](([0-9]+)\(FP\))`)
 	asmSP        = re(`[^+\-0-9](([0-9]+)\(([A-Z0-9]+)\))`)
 	asmOpcode    = re(`^\s*(?:[A-Z0-9a-z_]+:)?\s*([A-Z]+)\s*([^,]*)(?:,\s*(.*))?`)
-	power64Suff  = re(`([BHWD])(ZU|Z|U|BR)?$`)
+	ppc64Suff    = re(`([BHWD])(ZU|Z|U|BR)?$`)
 )
 
 func asmCheck(pkg *Package) {
@@ -589,9 +589,9 @@ func asmCheckVar(badf func(string, ...interface{}), fn *asmFunc, line, expr stri
 			case 'D', 'Q':
 				src = 8
 			}
-		case "power64", "power64le":
+		case "ppc64", "ppc64le":
 			// Strip standard suffixes to reveal size letter.
-			m := power64Suff.FindStringSubmatch(op)
+			m := ppc64Suff.FindStringSubmatch(op)
 			if m != nil {
 				switch m[1][0] {
 				case 'B':
diff --git a/src/cmd/yacc/yacc.go b/src/cmd/yacc/yacc.go
index 53c0fab..4f83f50 100644
--- a/src/cmd/yacc/yacc.go
+++ b/src/cmd/yacc/yacc.go
@@ -699,18 +699,20 @@ outer:
 		}
 	}
 
-	// put out names of token names
+	// put out names of tokens
 	ftable.WriteRune('\n')
 	fmt.Fprintf(ftable, "var %sToknames = [...]string{\n", prefix)
 	for i := 1; i <= ntokens; i++ {
-		fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name)
+		fmt.Fprintf(ftable, "\t%q,\n", tokset[i].name)
 	}
 	fmt.Fprintf(ftable, "}\n")
 
-	// put out names of state names
+	// put out names of states.
+	// commented out to avoid a huge table just for debugging.
+	// re-enable to have the names in the binary.
 	fmt.Fprintf(ftable, "var %sStatenames = [...]string{", prefix)
 	//	for i:=TOKSTART; i<=ntokens; i++ {
-	//		fmt.Fprintf(ftable, "\t\"%v\",\n", tokset[i].name);
+	//		fmt.Fprintf(ftable, "\t%q,\n", tokset[i].name);
 	//	}
 	fmt.Fprintf(ftable, "}\n")
 
@@ -3471,6 +3473,7 @@ func ($$rcvr *$$ParserImpl) Parse($$lex $$Lexer) int {
 	var $$lval $$SymType
 	var $$VAL $$SymType
 	var $$Dollar []$$SymType
+	_ = $$Dollar // silence set and not used
 	$$S := make([]$$SymType, $$MaxDepth)
 
 	Nerrs := 0   /* number of errors */
diff --git a/src/fmt/scan.go b/src/fmt/scan.go
index 21ed091..5b9b516 100644
--- a/src/fmt/scan.go
+++ b/src/fmt/scan.go
@@ -888,7 +888,6 @@ func hexDigit(d rune) (int, bool) {
 func (s *ss) hexByte() (b byte, ok bool) {
 	rune1 := s.getRune()
 	if rune1 == eof {
-		s.UnreadRune()
 		return
 	}
 	value1, ok := hexDigit(rune1)
diff --git a/src/fmt/scan_test.go b/src/fmt/scan_test.go
index 694f93e..a378436 100644
--- a/src/fmt/scan_test.go
+++ b/src/fmt/scan_test.go
@@ -1128,3 +1128,31 @@ func TestScanfNewlineMatchFormat(t *testing.T) {
 		}
 	}
 }
+
+// Test for issue 12090: Was unreading at EOF, double-scanning a byte.
+
+type hexBytes [2]byte
+
+func (h *hexBytes) Scan(ss ScanState, verb rune) error {
+	var b []byte
+	_, err := Fscanf(ss, "%4x", &b)
+	if err != nil {
+		panic(err) // Really shouldn't happen.
+	}
+	copy((*h)[:], b)
+	return err
+}
+
+func TestHexByte(t *testing.T) {
+	var h hexBytes
+	n, err := Sscanln("0123\n", &h)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if n != 1 {
+		t.Fatalf("expected 1 item; scanned %d", n)
+	}
+	if h[0] != 0x01 || h[1] != 0x23 {
+		t.Fatalf("expected 0123 got %x", h)
+	}
+}
diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go
index d9d5f03..cb89d65 100644
--- a/src/net/cgo_unix.go
+++ b/src/net/cgo_unix.go
@@ -222,6 +222,11 @@ func cgoLookupPTR(addr string) ([]string, error, bool) {
 			break
 		}
 	}
+	// Add trailing dot to match pure Go reverse resolver
+	// and all other lookup routines. See golang.org/issue/12189.
+	if len(b) > 0 && b[len(b)-1] != '.' {
+		b = append(b, '.')
+	}
 	return []string{string(b)}, nil, true
 }
 
diff --git a/src/net/conf.go b/src/net/conf.go
index 01bb585..c92e579 100644
--- a/src/net/conf.go
+++ b/src/net/conf.go
@@ -19,7 +19,7 @@ type conf struct {
 	// forceCgoLookupHost forces CGO to always be used, if available.
 	forceCgoLookupHost bool
 
-	netGo  bool // "netgo" build tag in use (or no cgo)
+	netGo  bool // go DNS resolution forced
 	netCgo bool // cgo DNS resolution forced
 
 	// machine has an /etc/mdns.allow file
@@ -112,6 +112,12 @@ func initConfVal() {
 	}
 }
 
+// canUseCgo reports whether calling cgo functions is allowed
+// for non-hostname lookups.
+func (c *conf) canUseCgo() bool {
+	return c.hostLookupOrder("") == hostLookupCgo
+}
+
 // hostLookupOrder determines which strategy to use to resolve hostname.
 func (c *conf) hostLookupOrder(hostname string) (ret hostLookupOrder) {
 	if c.dnsDebugLevel > 1 {
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 1b292ea..a3e4355 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -473,7 +473,7 @@ func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) {
 	if debugServerConnections {
 		c.rwc = newLoggingConn("server", c.rwc)
 	}
-	c.sr = liveSwitchReader{r: c.rwc}
+	c.sr.r = c.rwc
 	c.lr = io.LimitReader(&c.sr, noLimit).(*io.LimitedReader)
 	br := newBufioReader(c.lr)
 	bw := newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)
@@ -2015,10 +2015,7 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
 	if addr == "" {
 		addr = ":https"
 	}
-	config := &tls.Config{}
-	if srv.TLSConfig != nil {
-		*config = *srv.TLSConfig
-	}
+	config := cloneTLSConfig(srv.TLSConfig)
 	if config.NextProtos == nil {
 		config.NextProtos = []string{"http/1.1"}
 	}
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 09434f1..70d1864 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -645,16 +645,9 @@ func (t *Transport) dialConn(cm connectMethod) (*persistConn, error) {
 
 	if cm.targetScheme == "https" && !tlsDial {
 		// Initiate TLS and check remote host name against certificate.
-		cfg := t.TLSClientConfig
-		if cfg == nil || cfg.ServerName == "" {
-			host := cm.tlsHost()
-			if cfg == nil {
-				cfg = &tls.Config{ServerName: host}
-			} else {
-				clone := *cfg // shallow clone
-				clone.ServerName = host
-				cfg = &clone
-			}
+		cfg := cloneTLSClientConfig(t.TLSClientConfig)
+		if cfg.ServerName == "" {
+			cfg.ServerName = cm.tlsHost()
 		}
 		plainConn := pconn.conn
 		tlsConn := tls.Client(plainConn, cfg)
@@ -1399,3 +1392,70 @@ func isNetWriteError(err error) bool {
 		return false
 	}
 }
+
+// cloneTLSConfig returns a shallow clone of the exported
+// fields of cfg, ignoring the unexported sync.Once, which
+// contains a mutex and must not be copied.
+//
+// The cfg must not be in active use by tls.Server, or else
+// there can still be a race with tls.Server updating SessionTicketKey
+// and our copying it, and also a race with the server setting
+// SessionTicketsDisabled=false on failure to set the random
+// ticket key.
+//
+// If cfg is nil, a new zero tls.Config is returned.
+func cloneTLSConfig(cfg *tls.Config) *tls.Config {
+	if cfg == nil {
+		return &tls.Config{}
+	}
+	return &tls.Config{
+		Rand:                     cfg.Rand,
+		Time:                     cfg.Time,
+		Certificates:             cfg.Certificates,
+		NameToCertificate:        cfg.NameToCertificate,
+		GetCertificate:           cfg.GetCertificate,
+		RootCAs:                  cfg.RootCAs,
+		NextProtos:               cfg.NextProtos,
+		ServerName:               cfg.ServerName,
+		ClientAuth:               cfg.ClientAuth,
+		ClientCAs:                cfg.ClientCAs,
+		InsecureSkipVerify:       cfg.InsecureSkipVerify,
+		CipherSuites:             cfg.CipherSuites,
+		PreferServerCipherSuites: cfg.PreferServerCipherSuites,
+		SessionTicketsDisabled:   cfg.SessionTicketsDisabled,
+		SessionTicketKey:         cfg.SessionTicketKey,
+		ClientSessionCache:       cfg.ClientSessionCache,
+		MinVersion:               cfg.MinVersion,
+		MaxVersion:               cfg.MaxVersion,
+		CurvePreferences:         cfg.CurvePreferences,
+	}
+}
+
+// cloneTLSClientConfig is like cloneTLSConfig but omits
+// the fields SessionTicketsDisabled and SessionTicketKey.
+// This makes it safe to call cloneTLSClientConfig on a config
+// in active use by a server.
+func cloneTLSClientConfig(cfg *tls.Config) *tls.Config {
+	if cfg == nil {
+		return &tls.Config{}
+	}
+	return &tls.Config{
+		Rand:                     cfg.Rand,
+		Time:                     cfg.Time,
+		Certificates:             cfg.Certificates,
+		NameToCertificate:        cfg.NameToCertificate,
+		GetCertificate:           cfg.GetCertificate,
+		RootCAs:                  cfg.RootCAs,
+		NextProtos:               cfg.NextProtos,
+		ServerName:               cfg.ServerName,
+		ClientAuth:               cfg.ClientAuth,
+		ClientCAs:                cfg.ClientCAs,
+		InsecureSkipVerify:       cfg.InsecureSkipVerify,
+		CipherSuites:             cfg.CipherSuites,
+		PreferServerCipherSuites: cfg.PreferServerCipherSuites,
+		ClientSessionCache:       cfg.ClientSessionCache,
+		MinVersion:               cfg.MinVersion,
+		MaxVersion:               cfg.MaxVersion,
+		CurvePreferences:         cfg.CurvePreferences,
+	}
+}
diff --git a/src/net/lookup_test.go b/src/net/lookup_test.go
index a42ae29..86957b5 100644
--- a/src/net/lookup_test.go
+++ b/src/net/lookup_test.go
@@ -5,6 +5,7 @@
 package net
 
 import (
+	"bytes"
 	"fmt"
 	"strings"
 	"testing"
@@ -392,3 +393,111 @@ func TestLookupIPDeadline(t *testing.T) {
 	// happen due to issue 4856 for now.
 	t.Logf("%v succeeded, %v failed (%v timeout, %v temporary, %v other, %v unknown)", qstats.succeeded, qstats.failed, qstats.timeout, qstats.temporary, qstats.other, qstats.unknown)
 }
+
+func TestLookupDots(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skipf("skipping external network test")
+	}
+
+	fixup := forceGoDNS()
+	defer fixup()
+	testDots(t, "go")
+
+	if forceCgoDNS() {
+		testDots(t, "cgo")
+	}
+}
+
+func testDots(t *testing.T, mode string) {
+	names, err := LookupAddr("8.8.8.8") // Google dns server
+	if err != nil {
+		t.Errorf("LookupAddr(8.8.8.8): %v (mode=%v)", err, mode)
+	} else {
+		for _, name := range names {
+			if !strings.HasSuffix(name, ".google.com.") {
+				t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com. with trailing dot (mode=%v)", names, mode)
+				break
+			}
+		}
+	}
+
+	cname, err := LookupCNAME("www.mit.edu")
+	if err != nil || !strings.HasSuffix(cname, ".") {
+		t.Errorf("LookupCNAME(www.mit.edu) = %v, %v, want cname ending in . with trailing dot (mode=%v)", cname, err, mode)
+	}
+
+	mxs, err := LookupMX("google.com")
+	if err != nil {
+		t.Errorf("LookupMX(google.com): %v (mode=%v)", err, mode)
+	} else {
+		for _, mx := range mxs {
+			if !strings.HasSuffix(mx.Host, ".google.com.") {
+				t.Errorf("LookupMX(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)", mxString(mxs), mode)
+				break
+			}
+		}
+	}
+
+	nss, err := LookupNS("google.com")
+	if err != nil {
+		t.Errorf("LookupNS(google.com): %v (mode=%v)", err, mode)
+	} else {
+		for _, ns := range nss {
+			if !strings.HasSuffix(ns.Host, ".google.com.") {
+				t.Errorf("LookupNS(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)", nsString(nss), mode)
+				break
+			}
+		}
+	}
+
+	cname, srvs, err := LookupSRV("xmpp-server", "tcp", "google.com")
+	if err != nil {
+		t.Errorf("LookupSRV(xmpp-server, tcp, google.com): %v (mode=%v)", err, mode)
+	} else {
+		if !strings.HasSuffix(cname, ".google.com.") {
+			t.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned cname=%v, want name ending in .google.com. with trailing dot (mode=%v)", cname, mode)
+		}
+		for _, srv := range srvs {
+			if !strings.HasSuffix(srv.Target, ".google.com.") {
+				t.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned addrs=%v, want names ending in .google.com. with trailing dot (mode=%v)", srvString(srvs), mode)
+				break
+			}
+		}
+	}
+}
+
+func mxString(mxs []*MX) string {
+	var buf bytes.Buffer
+	sep := ""
+	fmt.Fprintf(&buf, "[")
+	for _, mx := range mxs {
+		fmt.Fprintf(&buf, "%s%s:%d", sep, mx.Host, mx.Pref)
+		sep = " "
+	}
+	fmt.Fprintf(&buf, "]")
+	return buf.String()
+}
+
+func nsString(nss []*NS) string {
+	var buf bytes.Buffer
+	sep := ""
+	fmt.Fprintf(&buf, "[")
+	for _, ns := range nss {
+		fmt.Fprintf(&buf, "%s%s", sep, ns.Host)
+		sep = " "
+	}
+	fmt.Fprintf(&buf, "]")
+	return buf.String()
+}
+
+func srvString(srvs []*SRV) string {
+	var buf bytes.Buffer
+	sep := ""
+	fmt.Fprintf(&buf, "[")
+	for _, srv := range srvs {
+		fmt.Fprintf(&buf, "%s%s:%d:%d:%d", sep, srv.Target, srv.Port, srv.Priority, srv.Weight)
+		sep = " "
+	}
+	fmt.Fprintf(&buf, "]")
+	return buf.String()
+}
diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go
index 1c811d2..a64da8b 100644
--- a/src/net/lookup_unix.go
+++ b/src/net/lookup_unix.go
@@ -74,19 +74,21 @@ func lookupIP(host string) (addrs []IPAddr, err error) {
 }
 
 func lookupPort(network, service string) (int, error) {
-	port, err, ok := cgoLookupPort(network, service)
-	if !ok {
-		port, err = goLookupPort(network, service)
+	if systemConf().canUseCgo() {
+		if port, err, ok := cgoLookupPort(network, service); ok {
+			return port, err
+		}
 	}
-	return port, err
+	return goLookupPort(network, service)
 }
 
 func lookupCNAME(name string) (string, error) {
-	cname, err, ok := cgoLookupCNAME(name)
-	if !ok {
-		cname, err = goLookupCNAME(name)
+	if systemConf().canUseCgo() {
+		if cname, err, ok := cgoLookupCNAME(name); ok {
+			return cname, err
+		}
 	}
-	return cname, err
+	return goLookupCNAME(name)
 }
 
 func lookupSRV(service, proto, name string) (string, []*SRV, error) {
@@ -148,9 +150,10 @@ func lookupTXT(name string) ([]string, error) {
 }
 
 func lookupAddr(addr string) ([]string, error) {
-	ptrs, err, ok := cgoLookupPTR(addr)
-	if !ok {
-		ptrs, err = goLookupPTR(addr)
+	if systemConf().canUseCgo() {
+		if ptrs, err, ok := cgoLookupPTR(addr); ok {
+			return ptrs, err
+		}
 	}
-	return ptrs, err
+	return goLookupPTR(addr)
 }
diff --git a/src/net/mail/message.go b/src/net/mail/message.go
index 8ddb313..266ac50 100644
--- a/src/net/mail/message.go
+++ b/src/net/mail/message.go
@@ -171,7 +171,14 @@ func (a *Address) String() string {
 
 	// Format address local at domain
 	at := strings.LastIndex(a.Address, "@")
-	local, domain := a.Address[:at], a.Address[at+1:]
+	var local, domain string
+	if at < 0 {
+		// This is a malformed address ("@" is required in addr-spec);
+		// treat the whole address as local-part.
+		local = a.Address
+	} else {
+		local, domain = a.Address[:at], a.Address[at+1:]
+	}
 
 	// Add quotes if needed
 	// TODO: rendering quoted local part and rendering printable name
diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go
index ffe9af9..1b42274 100644
--- a/src/net/mail/message_test.go
+++ b/src/net/mail/message_test.go
@@ -483,6 +483,14 @@ func TestAddressFormatting(t *testing.T) {
 			&Address{Name: "Böb Jacöb", Address: "bob at example.com"},
 			`=?utf-8?q?B=C3=B6b_Jac=C3=B6b?= <bob at example.com>`,
 		},
+		{ // https://golang.org/issue/12098
+			&Address{Name: "Rob", Address: ""},
+			`"Rob" <@>`,
+		},
+		{ // https://golang.org/issue/12098
+			&Address{Name: "Rob", Address: "@"},
+			`"Rob" <@>`,
+		},
 	}
 	for _, test := range tests {
 		s := test.addr.String()
diff --git a/src/net/net.go b/src/net/net.go
index 75510a2..6e84c3a 100644
--- a/src/net/net.go
+++ b/src/net/net.go
@@ -35,6 +35,46 @@ The Listen function creates servers:
 		}
 		go handleConnection(conn)
 	}
+
+Name Resolution
+
+The method for resolving domain names, whether indirectly with functions like Dial
+or directly with functions like LookupHost and LookupAddr, varies by operating system.
+
+On Unix systems, the resolver has two options for resolving names.
+It can use a pure Go resolver that sends DNS requests directly to the servers
+listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C
+library routines such as getaddrinfo and getnameinfo.
+
+By default the pure Go resolver is used, because a blocked DNS request consumes
+only a goroutine, while a blocked C call consumes an operating system thread.
+When cgo is available, the cgo-based resolver is used instead under a variety of
+conditions: on systems that do not let programs make direct DNS requests (OS X),
+when the LOCALDOMAIN environment variable is present (even if empty),
+when the RES_OPTIONS or HOSTALIASES environment variable is non-empty,
+when the ASR_CONFIG environment variable is non-empty (OpenBSD only),
+when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the
+Go resolver does not implement, and when the name being looked up ends in .local
+or is an mDNS name.
+
+The resolver decision can be overridden by setting the netdns value of the
+GODEBUG environment variable (see package runtime) to go or cgo, as in:
+
+	export GODEBUG=netdns=go    # force pure Go resolver
+	export GODEBUG=netdns=cgo   # force cgo resolver
+
+The decision can also be forced while building the Go source tree
+by setting the netgo or netcgo build tag.
+
+A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver
+to print debugging information about its decisions.
+To force a particular resolver while also printing debugging information,
+join the two settings by a plus sign, as in GODEBUG=netdns=go+1.
+
+On Plan 9, the resolver always accesses /net/cs and /net/dns.
+
+On Windows, the resolver always uses C library functions, such as GetAddrInfo and DnsQuery.
+
 */
 package net
 
diff --git a/src/net/non_unix_test.go b/src/net/non_unix_test.go
new file mode 100644
index 0000000..eddca56
--- /dev/null
+++ b/src/net/non_unix_test.go
@@ -0,0 +1,11 @@
+// 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.
+
+// +build nacl plan9 windows
+
+package net
+
+// See unix_test.go for what these (don't) do.
+func forceGoDNS() func() { return func() {} }
+func forceCgoDNS() bool  { return false }
diff --git a/src/net/unix_test.go b/src/net/unix_test.go
index 59f5c2d..358ff31 100644
--- a/src/net/unix_test.go
+++ b/src/net/unix_test.go
@@ -404,3 +404,28 @@ func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
 		}
 	}
 }
+
+// forceGoDNS forces the resolver configuration to use the pure Go resolver
+// and returns a fixup function to restore the old settings.
+func forceGoDNS() func() {
+	c := systemConf()
+	oldGo := c.netGo
+	oldCgo := c.netCgo
+	fixup := func() {
+		c.netGo = oldGo
+		c.netCgo = oldCgo
+	}
+	c.netGo = true
+	c.netCgo = false
+	return fixup
+}
+
+// forceCgoDNS forces the resolver configuration to use the cgo resolver
+// and returns true to indicate that it did so.
+// (On non-Unix systems forceCgoDNS returns false.)
+func forceCgoDNS() bool {
+	c := systemConf()
+	c.netGo = false
+	c.netCgo = true
+	return true
+}
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index 91dccdc..9c32e42 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -752,6 +752,8 @@ TEXT runtime·atomicstoreuintptr(SB),NOSPLIT,$0-8
 	B	runtime·atomicstore(SB)
 
 // armPublicationBarrier is a native store/store barrier for ARMv7+.
+// On earlier ARM revisions, armPublicationBarrier is a no-op.
+// This will not work on SMP ARMv6 machines, if any are in use.
 // To implement publiationBarrier in sys_$GOOS_arm.s using the native
 // instructions, use:
 //
@@ -759,6 +761,9 @@ TEXT runtime·atomicstoreuintptr(SB),NOSPLIT,$0-8
 //		B	runtime·armPublicationBarrier(SB)
 //
 TEXT runtime·armPublicationBarrier(SB),NOSPLIT,$-4-0
+	MOVB	runtime·goarm(SB), R11
+	CMP	$7, R11
+	BLT	2(PC)
 	WORD $0xf57ff05e	// DMB ST
 	RET
 
diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go
index c439158..fd6b4b1 100644
--- a/src/runtime/mbitmap.go
+++ b/src/runtime/mbitmap.go
@@ -109,6 +109,9 @@ func add1(p *byte) *byte {
 
 // subtract1 returns the byte pointer p-1.
 //go:nowritebarrier
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//go:nosplit
 func subtract1(p *byte) *byte {
 	// Note: wrote out full expression instead of calling subtractb(p, 1)
 	// to reduce the number of temporaries generated by the
@@ -245,6 +248,9 @@ func (h heapBits) prefetch() {
 // next returns the heapBits describing the next pointer-sized word in memory.
 // That is, if h describes address p, h.next() describes p+ptrSize.
 // Note that next does not modify h. The caller must record the result.
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//go:nosplit
 func (h heapBits) next() heapBits {
 	if h.shift < 3*heapBitsShift {
 		return heapBits{h.bitp, h.shift + heapBitsShift}
@@ -293,6 +299,9 @@ func (h heapBits) setMarkedNonAtomic() {
 
 // isPointer reports whether the heap bits describe a pointer word.
 // h must describe the initial word of the object.
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//go:nosplit
 func (h heapBits) isPointer() bool {
 	return (*h.bitp>>h.shift)&bitPointer != 0
 }
diff --git a/src/runtime/os1_darwin.go b/src/runtime/os1_darwin.go
index 08ec611..e070229 100644
--- a/src/runtime/os1_darwin.go
+++ b/src/runtime/os1_darwin.go
@@ -34,14 +34,19 @@ func osinit() {
 	// bsdthread_register delayed until end of goenvs so that we
 	// can look at the environment first.
 
+	ncpu = getncpu()
+}
+
+func getncpu() int32 {
 	// Use sysctl to fetch hw.ncpu.
 	mib := [2]uint32{6, 3}
 	out := uint32(0)
 	nout := unsafe.Sizeof(out)
 	ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
-	if ret >= 0 {
-		ncpu = int32(out)
+	if ret >= 0 && int32(out) > 0 {
+		return int32(out)
 	}
+	return 1
 }
 
 var urandom_dev = []byte("/dev/urandom\x00")
diff --git a/src/runtime/os_darwin_arm.go b/src/runtime/os_darwin_arm.go
index d3336c0..1ccc959 100644
--- a/src/runtime/os_darwin_arm.go
+++ b/src/runtime/os_darwin_arm.go
@@ -5,7 +5,14 @@
 package runtime
 
 func checkgoarm() {
-	return // TODO(minux)
+	// TODO(minux): FP checks like in os_linux_arm.go.
+
+	// osinit not called yet, so ncpu not set: must use getncpu directly.
+	if getncpu() > 1 && goarm < 7 {
+		print("runtime: this system has multiple CPUs and must use\n")
+		print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+		exit(1)
+	}
 }
 
 //go:nosplit
diff --git a/src/runtime/os_freebsd_arm.go b/src/runtime/os_freebsd_arm.go
index e049cbf..1f2add2 100644
--- a/src/runtime/os_freebsd_arm.go
+++ b/src/runtime/os_freebsd_arm.go
@@ -5,7 +5,14 @@
 package runtime
 
 func checkgoarm() {
-	// TODO(minux)
+	// TODO(minux): FP checks like in os_linux_arm.go.
+
+	// osinit not called yet, so ncpu not set: must use getncpu directly.
+	if getncpu() > 1 && goarm < 7 {
+		print("runtime: this system has multiple CPUs and must use\n")
+		print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+		exit(1)
+	}
 }
 
 //go:nosplit
diff --git a/src/runtime/os_linux_arm.go b/src/runtime/os_linux_arm.go
index 6c74c81..3749640 100644
--- a/src/runtime/os_linux_arm.go
+++ b/src/runtime/os_linux_arm.go
@@ -19,7 +19,6 @@ const (
 var randomNumber uint32
 var armArch uint8 = 6 // we default to ARMv6
 var hwcap uint32      // set by setup_auxv
-var goarm uint8       // set by 5l
 
 func checkgoarm() {
 	if goarm > 5 && hwcap&_HWCAP_VFP == 0 {
diff --git a/src/runtime/os_nacl_arm.go b/src/runtime/os_nacl_arm.go
index a43e7c4..f94c183 100644
--- a/src/runtime/os_nacl_arm.go
+++ b/src/runtime/os_nacl_arm.go
@@ -5,7 +5,13 @@
 package runtime
 
 func checkgoarm() {
-	return // NaCl/ARM only supports ARMv7
+	// TODO(minux): FP checks like in os_linux_arm.go.
+
+	// NaCl/ARM only supports ARMv7
+	if goarm != 7 {
+		print("runtime: NaCl requires ARMv7. Recompile using GOARM=7.\n")
+		exit(1)
+	}
 }
 
 //go:nosplit
diff --git a/src/runtime/os_netbsd_arm.go b/src/runtime/os_netbsd_arm.go
index 83c4c06..03032e8 100644
--- a/src/runtime/os_netbsd_arm.go
+++ b/src/runtime/os_netbsd_arm.go
@@ -16,7 +16,14 @@ func lwp_mcontext_init(mc *mcontextt, stk unsafe.Pointer, mp *m, gp *g, fn uintp
 }
 
 func checkgoarm() {
-	// TODO(minux)
+	// TODO(minux): FP checks like in os_linux_arm.go.
+
+	// osinit not called yet, so ncpu not set: must use getncpu directly.
+	if getncpu() > 1 && goarm < 7 {
+		print("runtime: this system has multiple CPUs and must use\n")
+		print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+		exit(1)
+	}
 }
 
 //go:nosplit
diff --git a/src/runtime/os_openbsd_arm.go b/src/runtime/os_openbsd_arm.go
index be3f330..b46fef0 100644
--- a/src/runtime/os_openbsd_arm.go
+++ b/src/runtime/os_openbsd_arm.go
@@ -5,7 +5,14 @@
 package runtime
 
 func checkgoarm() {
-	// TODO(minux)
+	// TODO(minux): FP checks like in os_linux_arm.go.
+
+	// osinit not called yet, so ncpu not set: must use getncpu directly.
+	if getncpu() > 1 && goarm < 7 {
+		print("runtime: this system has multiple CPUs and must use\n")
+		print("atomic synchronization instructions. Recompile using GOARM=7.\n")
+		exit(1)
+	}
 }
 
 //go:nosplit
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index c8158b9..a166281 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -327,7 +327,7 @@ func Goexit() {
 		freedefer(d)
 		// Note: we ignore recovers here because Goexit isn't a panic
 	}
-	goexit()
+	goexit1()
 }
 
 // Print all currently active panics.  Used when crashing.
diff --git a/src/runtime/proc1.go b/src/runtime/proc1.go
index 23beaf5..09cb775 100644
--- a/src/runtime/proc1.go
+++ b/src/runtime/proc1.go
@@ -1348,7 +1348,23 @@ func execute(gp *g, inheritTime bool) {
 		// GoSysExit has to happen when we have a P, but before GoStart.
 		// So we emit it here.
 		if gp.syscallsp != 0 && gp.sysblocktraced {
-			traceGoSysExit(gp.sysexitseq, gp.sysexitticks)
+			// Since gp.sysblocktraced is true, we must emit an event.
+			// There is a race between the code that initializes sysexitseq
+			// and sysexitticks (in exitsyscall, which runs without a P,
+			// and therefore is not stopped with the rest of the world)
+			// and the code that initializes a new trace.
+			// The recorded sysexitseq and sysexitticks must therefore
+			// be treated as "best effort". If they are valid for this trace,
+			// then great, use them for greater accuracy.
+			// But if they're not valid for this trace, assume that the
+			// trace was started after the actual syscall exit (but before
+			// we actually managed to start the goroutine, aka right now),
+			// and assign a fresh time stamp to keep the log consistent.
+			seq, ts := gp.sysexitseq, gp.sysexitticks
+			if seq == 0 || int64(seq)-int64(trace.seqStart) < 0 {
+				seq, ts = tracestamp()
+			}
+			traceGoSysExit(seq, ts)
 		}
 		traceGoStart()
 	}
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index a157f01..57cd869 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -645,6 +645,8 @@ var (
 	cpuid_ecx         uint32
 	cpuid_edx         uint32
 	lfenceBeforeRdtsc bool
+
+	goarm uint8 // set by cmd/link on arm systems
 )
 
 // Set by the linker so the runtime can determine the buildmode.
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
index e6b0156..d725bb1 100644
--- a/src/runtime/stubs.go
+++ b/src/runtime/stubs.go
@@ -128,7 +128,20 @@ func breakpoint()
 func reflectcall(argtype *_type, fn, arg unsafe.Pointer, argsize uint32, retoffset uint32)
 
 func procyield(cycles uint32)
-func goexit()
+
+type neverCallThisFunction struct{}
+
+// goexit is the return stub at the top of every goroutine call stack.
+// Each goroutine stack is constructed as if goexit called the
+// goroutine's entry point function, so that when the entry point
+// function returns, it will return to goexit, which will call goexit1
+// to perform the actual exit.
+//
+// This function must never be called directly. Call goexit1 instead.
+// gentraceback assumes that goexit terminates the stack. A direct
+// call on the stack will cause gentraceback to stop walking the stack
+// prematurely and if there are leftover stack barriers it may panic.
+func goexit(neverCallThisFunction)
 
 // Not all cgocallback_gofunc frames are actually cgocallback_gofunc,
 // so not all have these arguments. Mark them uintptr so that the GC
diff --git a/src/sort/sort.go b/src/sort/sort.go
index 0a446c8..c7c3042 100644
--- a/src/sort/sort.go
+++ b/src/sort/sort.go
@@ -300,7 +300,7 @@ func StringsAreSorted(a []string) bool { return IsSorted(StringSlice(a)) }
 //    V. Raman in Algorithmica (1996) 16, 115-160:
 //    This algorithm either needs additional 2n bits or works only if there
 //    are enough different elements available to encode some permutations
-//    which have to be undone later (so not stable an any input).
+//    which have to be undone later (so not stable on any input).
 //  - All the optimal in-place sorting/merging algorithms I found are either
 //    unstable or rely on enough different elements in each step to encode the
 //    performed block rearrangements. See also "In-Place Merging Algorithms",
diff --git a/test/fixedbugs/issue12133.go b/test/fixedbugs/issue12133.go
new file mode 100644
index 0000000..0b66c56
--- /dev/null
+++ b/test/fixedbugs/issue12133.go
@@ -0,0 +1,26 @@
+// run
+
+// 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.
+
+// Issue 12133.  The CX register was getting clobbered
+// because we did not keep track of its allocation correctly.
+
+package main
+
+import "fmt"
+
+func main() {
+	want := uint(48)
+	got := f1(48)
+	if got != want {
+		fmt.Println("got", got, ", wanted", want)
+		panic("bad")
+	}
+}
+func f1(v1 uint) uint {
+	switch {
+	} // prevent inlining
+	return v1 >> ((1 >> v1) + (1 >> v1))
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-golang/golang.git



More information about the pkg-golang-commits mailing list